my first dll doesn't work

Started by
19 comments, last by temp_ie_cant_thinkof_name 20 years ago
quote:Original post by temp_ie_cant_thinkof_name
__declspec(dllexport) void myPrintString(char *string);

void myPrintString(char *string)
{ ... }
Declaration and definition signatures don''t match.
Advertisement
quote:Original post by SiCrane
It could be an issue with name mangling.
Exactly. The difference in calling conventions between declaration and definition could modify the actual entry into the export table.
Okay, I''m going to make a new, clean project for both the app and dll, to get rid of some variables. One question: the option in VS.NET to "Export Symbols (only for dll)"-- should I select that or not? I think I selected that option when making this project, and I don''t know where to change it back, so I''m going to make one with and one w/o to test.
"I study differential and integral calculus in my spare time." -- Karl Marx
quote:Original post by Oluseyi
quote:Original post by temp_ie_cant_thinkof_name
__declspec(dllexport) void myPrintString(char *string);

void myPrintString(char *string)
{ ... }
Declaration and definition signatures don''t match.


Actually, that doesn''t matter. Due to the joy of the way that the linkage specifier propogates, only the declaration needs to be declared __declspec(dllexport); the apparant function signature of the definition doesn''t need to match. In actuallity __declspec(dllexport) is not actually a part of the function signature, so does not contribute to name mangling.
The "Export Symbols" option I was talking about didn't change anything when I selected, it, but I also made an empty project. I'll have to check again to see if that option generates a mod def file for you. But Here's what I'm testing, and I'm getting the PROC_NOT_FOUND error:
A0_MYAPP.exe
/*Main.h:#include <windows.h>#include <stdio.h>__declspec(dllimport) void testInteger(void);*/#include "Main.h"typedef int (*TestFunc)(void);TestFunc getTestInt;HINSTANCE h_dll;void main(void){	h_dll = LoadLibrary("A0_MYDLL");	if(h_dll != NULL)	{		getTestInt = (TestFunc)GetProcAddress(h_dll, "testInteger");		if(!getTestInt)		{			printf("%d\n", GetLastError());			FreeLibrary(h_dll);		}		else		{  			printf("%d\n", getTestInt());//should print 47 if successful			printf("--Is 47 if successful");		}	}	else	{			printf("%d\n", GetLastError());	}} 


A0_MYDLL.dll
/*Main.h:#include <windows.h>#include <stdio.h>__declspec(dllexport) int testInteger(void);*/#include "Main.h"int testInteger(void){	return 47;} 


EDIT: urgh, source tags

[edited by - temp_ie_cant_thinkof_name on March 21, 2004 6:46:54 PM]
"I study differential and integral calculus in my spare time." -- Karl Marx
If that''s all you''re doing the the name being exported by your DLL is probably something screwy like "?testInteger@@YAHXZ". Run dumpbin /exports on your DLL and see what it spits out.
I ran dumpbin on my dll and it gave:
ordinal hint RVA       name      1     0 000116F4 ?testInteger@@YAHXZ  


EDIT: I read a gamedev article that said something about 'extern "C" {}'ing the import decleration in my client app to force the C nameing style or something... well I thought it was just for older compilers... Maybe NOW, I'll try re- extern "C"'ing ... I'll get back to you. One question: do I have to exter "C" in my dll as well? Because the article just had it on the client app decl. I'll try both, anyway.

[edited by - temp_ie_cant_thinkof_name on March 21, 2004 7:04:59 PM]
"I study differential and integral calculus in my spare time." -- Karl Marx
As I said, it looks like you''re being bitten by name mangling.

One option is to use that "?testInteger@@YAHXZ" string to get the function, or you can try to get rid of the name mangling. As I said before, my preferred method of doing so is adding a .def file to the dll project.
Okay, I fixed it. You have to extern "C", on every declaration of the exported function "testInteger," even around the definition. I don''t know if you have to do the same or not to the imported decl, but I did in the test, and it works. Now, this should compile (and WORK):

A0_MYAPP.exe
/*Main.h:#include <windows.h>#include <stdio.h>extern "C"{__declspec(dllimport) void testInteger(void);}*/#include "Main.h"typedef int (*TestFunc)(void);TestFunc getTestInt;HINSTANCE h_dll;void main(void){	h_dll = LoadLibrary("A0_MYDLL");	if(h_dll != NULL)	{		getTestInt = (TestFunc)GetProcAddress(h_dll, "testInteger");		if(!getTestInt)		{			printf("%d\n", GetLastError());			FreeLibrary(h_dll);		}		else		{  			printf("%d\n", getTestInt());//should print 47 if successful			printf("--Is 47 if successful");		}	}	else	{			printf("%d\n", GetLastError());	}} 


A0_MYDLL.dll
/*Main.h:#include <windows.h>#include <stdio.h>extern "C"{__declspec(dllexport) int testInteger(void);}*/#include "Main.h"extern "C"{int testInteger(void){	return 47;}} 



"I study differential and integral calculus in my spare time." -- Karl Marx
Okay, problem fixed. I found that in VC++ 6.0 under VS.NET IDE 2003, you only need to ''extern "C" {}'' on the declaration of the exported function. So if you have a declaration header for exported funcs and a src file with the definitions you don''t need to put the extern "C" aroudn the definition, only the declaration in the header needs one. You can however, extern "C" everything, including the import decl in the client app and the definition decl in the dll, and it still works, but is not needed. So All I have to do now (to avoid making a def file) is in my export header do
extern "C"{   __declspec(dllexport) int testInteger(void);//....rest of exported funcs} 


Thanks SiCrane and Oluseyi for your help.
"I study differential and integral calculus in my spare time." -- Karl Marx

This topic is closed to new replies.

Advertisement