Click here to Skip to main content
15,896,726 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hello everyone! I just wanted to ask a question since google hasnt been able to provide an answer.....

You see every time I make a .dll and then have a .exe call a function from it, I get this error.

The value of the ESP was not properly saved across a function call.

Now I googled this and got alot of results. Mainly telling me to change my function call things....

There is only one function which is not declared as just a plain function and it is declared as such.
<br />
extern "C" __declspec(dllexport) int Compile(int argc, char* argv[])<br />
{<br />
     // function definition<br />
}


Now I read that i should change the function to be like this.

int _cdecl Compile(int argc, char* argv[])

or by using _stdcall. I have tried both, with and without extern "C", and even tried using just plain

int Compile(int argc, char* argv[])

but i still get the same error at runtime. Even though the program is done executing. The error actually appears AFTER the main function of the .exe has returned. I use int main and always return EXIT_SUCCESS or EXIT_FAILURE from the cstdlib library. If anyone can help me fix this it would be GREAT help for me.
I am using windows 7 service pack 1 and my compiler is Microsoft Visual C++ Express 2010 and I have also tried Visual C++ 6.0 with the same results each time.
Posted

If you use the Visual Studio wizard to generate DLL skeleton (specifying 'export symbols') then you may find, in the generated code, the following remark:

// The following ifdef block is the standard way of creating macros which make exporting
// from a DLL simpler. All files within this DLL are compiled with the MYDLL_EXPORTS
// symbol defined on the command line. This symbol should not be defined on any project
// that uses this DLL. This way any other project whose source files include this file see
// MYDLL_API functions as being imported from a DLL, whereas this DLL sees symbols
// defined with this macro as being exported.
#ifdef MYDLL_EXPORTS
#define MYDLL_API __declspec(dllexport)
#else
#define MYDLL_API __declspec(dllimport)
#endif 



I suppose it explains your problem: while the DLL build must use __declspec(dllexport), the application one should use __declspec(dllimport) (or don't use, in the application build, __declspec at all, see here[^]).
 
Share this answer
 
Comments
shahab96 9-Jul-11 9:29am    
I tried removing __declspec(dllimport) and it still didnt work....i also included __cdecl with the __declspec and even then it gave me the same error.

Do you think posting my code up would help find the problem?
Did you try to use this?
extern "C" __declspec(dllexport) int _cdecl Compile(int argc, char* argv[])
 
Share this answer
 
Comments
shahab96 10-Jul-11 4:19am    
Yes i have and i think maybe posting my code will help.

This is the .dll project files.

GoCompile.h

#ifdef UNICODE
#undef UNICODE
#endif

#include <windows.h>
#include <conio.h>
#include <cstdlib>
#include <iostream>

using std::cout;
using std::cerr;
using std::endl;

#include <string>

using std::string;

string command;

extern "C" __declspec(dllexport) int _cdecl Compile(int argc, char* argv[]);
int getParametersForCompile(int argc, char* argv[]);
int getParametersForLinking(int argc, char* argv[]);


GoCompile.cpp

#include "GoCompile.h"

#define CLS system("cls")
#define getch() (option = _getch())

char option;

extern "C" __declspec(dllexport) int _cdecl Compile(int argc, char* argv[])
{
if(argc < 2)
{
cerr << "Invalid number of arguments." << endl;
return EXIT_FAILURE;
}
command = "8g ";
if(getParametersForCompile(argc, argv) & EXIT_FAILURE)
return EXIT_FAILURE;
if(getParametersForLinking(argc, argv) & EXIT_FAILURE)
return EXIT_FAILURE;
return EXIT_SUCCESS;
}

int getParametersForCompile(int argc, char* argv[])
{
cout << "Would you like to include packages from a specific directory? <y\n>" << endl;
if(getch() == 'y')
{
char directory[50];
cout << "Please enter the directory." << endl;
std::cin.getline(directory, 50);
command.append("-I ").append(directory).append(" ");
}
CLS;
cout << "Would you like to have the compiler print declarations? <y\n>" << endl;
if(getch() == 'y')
command.append("-d ");
CLS;
cout << "Would you like to have the compiler remove limits on errors printed? <y\n>" << endl;
if(getch() == 'y')
command.append("-e ");
CLS;
cout << "Would you like to have the compiler print the stack frame structure? <y\n>" << endl;
if(getch() == 'y')
command.append("-f ");
CLS;
cout << "Would you like the compile to panic on error? <y\n>" << endl;
if(getch() == 'y')
command.append("-h ");
CLS;
cout << "Would you like to specify the package name? <y\n>" << endl;
if(getch() == 'y')
{
char name[50];
cout << "Please enter the package name." << endl;
std::cin.getline(name, 50);
command.append("-k ").append(name).append(" ");
}
CLS;
cout << "Would you like to specify the name of the output file? <y\n>" << endl;
if(getch() == 'y')
{
char output[50];
cout << "Please enter the output file name. (Including extention)" << endl;
std::cin.getline(output, 50);
command.append("-o ").append(output).append(" ");
}
CLS;
cout << "Would you like the compiler to print the assembly language? <y\n>" << endl;
if(getch() == 'y')
command.append("-S ");
CLS;
cout << "Would you like the compiler to print the parse tree? <y\n>" << endl;
if(getch() == 'y')
command.append("-w ");
CLS;
cout << "Would you like the compiler to print lex tokens? <y\n>" << endl;
if(getch() == 'y')
command.append("-x ");
CLS;
string command_temp;
for(short i = 1;i < argc;i++)
{
command_temp = command;
if(system(command_temp.append(argv[i]).append(".go").c_str()) == 0)
continue;
else return EXIT_FAILURE;
}
cout << "Press any key to link files." << endl;
_getch();
return EXIT_SUCCESS;
}

int getParametersForLinking(int argc, char* argv[])
{
CLS;
cout << "Would you like to specify a name for the executable? <y\n>" << endl;
command = "8l ";
string command_temp;
if(getch() =='y')
{
char name[50];
cout << "Please enter the executable name" << endl;
std::cin.getline(name, 50);
command.append("-o ").append(name).append(" ");
}
for(short i = 1;i < argc;i++)
{
command_temp = command;
if(system(command_temp.append(argv[i]).append(".8").c_str()) == 0)
continue;
else return EXIT_FAILURE;
}
cout << "Linking Succesful. Press any key to end session" << endl;
_getch();
return EXIT_SUCCESS;
}
shahab96 10-Jul-11 4:23am    
Oops...i think the code tags made my includs invisible. I've included

1) windows.h
2) conio.h
3) cstdlib
4) iostream

and no the cstdlib and iostream includes are not followed by .h in my code either.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
Top Experts
Last 24hrsThis month


CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900