我有一个C程序,我通过函数名称“dynamic”获取函数指针(即,我将函数名称作为string传递并获取指向该函数的指针)。 我已经使用dlopen和dlsym在Linux中执行了这个操作,我想它也可以在任何其他类似Unix的dlfcn中工作 。
当我尝试使用MinGW将此程序移植到Windows时,问题就开始了。 当我尝试使用“GetProcAddress(handle,symbol_name)”,其中“symbol_name”是我的callback函数的名称并且“handle”是由“GetModuleHandle(NULL)”返回的当前可执行文件的句柄来查找名称时,因为MinGW的名字会把我的符号名称加上一个“_”。
显而易见的解决scheme(在我想要的符号前加一个“_”)对于可移植性似乎有些“危险”(编译器可能为它们中的一些添加两个下划线?我不知道),所以,我问:
有一个更好的方法来防止编译器的名称,我的符号? (或它们的一个子集,只有我需要dynamic查找的callback);
还是让GetProcAddressfind它们的方法,即使是在被破坏的时候?
我也尝试了-fno-leading-underscore这个选项,但是也删除了所有外部符号,使得程序无法与stdlib等链接(同样,文档上的警告有点吓人)。
另外,请注意,我使用的是纯C–在我的代码的任何部分都没有C ++,而且我所有的代码都在一个“.exe”中。
TIA
不知道你的问题是什么,因为我不能用我能想到的最简单的DLL例子重现它:
/* hello_dll.c */ #include <stdio.h> __declspec(dllexport) void hello ( void ) { puts ( "Hello, DLL!"); } /* hello_exe.c */ #include <windows.h> #include <stdio.h> int main () { typedef void (*pfunc)(void); HANDLE hself; pfunc hello; hself = GetmoduleeHandle(NULL); hello = (pfunc)GetProcAddress(hdll, "hello"); hello(); return 0; }
这是使用MinGW gcc的命令行,没有特殊的标志,这一切工作:
gcc src\hello_dll.c src\hello_exe.c -o bin\hello.exe $ bin\hello.exe Hello, DLL! $ gcc --version gcc (GCC) 4.5.0
没有__declspec(dllexport)
如果你从自己得到这个函数,它是行不通的。 当使用gcc -shared
创建一个DLL时,它似乎不是必需的,但是如果从exe中导出函数似乎是必需的。
C不使用名称修改。 特别是,它不添加任何类型的信息名称(不像C ++)。 但是有些平台会对名称进行小小的修改,例如在下划线前加上字母。 与C ++不同,它只是平台特定的,而不是编译器特定的。
到目前为止,我所见过的所有平台上,我只看到没有修改或领先的下划线。
所以我建议你使用一些ifdefs来派生当前平台是否使用下划线。
(Windows对某些Windows API函数进行了一些小修改,以区分ANSI和Unicode版本,但这可能与您的情况无关)。
也许别人可以在不同的平台上指出C ABI的官方文档。