C++ 如何设置VC++;通过命令行动态链接?
虽然通过VisualStudio设置运行时DLL加载没有问题,但在通过VisualStudioCLI工具手动执行时遇到了一些问题C++ 如何设置VC++;通过命令行动态链接?,c++,visual-c++,dll,dynamic-linking,cl,C++,Visual C++,Dll,Dynamic Linking,Cl,虽然通过VisualStudio设置运行时DLL加载没有问题,但在通过VisualStudioCLI工具手动执行时遇到了一些问题 我们说下面有2个简单的C++源文件我们要编译,一个是二进制可执行文件,一个是DLL:< /P> main.cpp void say_hello(); int main() { say_hello(); return 0; } #include <stdio.h> void say_hello() { printf("Hello
我们说下面有2个简单的C++源文件我们要编译,一个是二进制可执行文件,一个是DLL:< /P> main.cpp
void say_hello();
int main()
{
say_hello();
return 0;
}
#include <stdio.h>
void say_hello()
{
printf("Hello DLL World!");
}
void say_hello();
int main()
{
say_hello();
return 0;
}
#include <stdio.h>
__declspec(dllexport) void say_hello()
{
printf("Hello DLL World!");
}
打招呼。cpp
void say_hello();
int main()
{
say_hello();
return 0;
}
#include <stdio.h>
void say_hello()
{
printf("Hello DLL World!");
}
void say_hello();
int main()
{
say_hello();
return 0;
}
#include <stdio.h>
__declspec(dllexport) void say_hello()
{
printf("Hello DLL World!");
}
不幸的是,这似乎只允许通过say_hello.lib
文件静态链接应用程序(可以通过删除.lib和.dll文件来确认,这仍然允许二进制文件成功运行)
我必须向编译/链接阶段传递哪些命令/参数才能使
main.exe
使用DLL而不是静态库?下面是一个示例。并非每件事都是完全必要的(例如,德尔曼),但我认为这些是你应该查阅的;-)
SayHello.cpp
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
// see https://msdn.microsoft.com/en-us/library/56h2zst2.aspx : Decorated Names
extern "C" { // somehow making it superfluous to put the code in SayHello.cPP ...but anyway ;-)
// see https://msdn.microsoft.com/en-us/library/3y1sfaz2.aspx : dllexport, dllimport
__declspec(dllexport) void say_hello()
{
printf("Hello DLL World!");
}
// see https://msdn.microsoft.com/en-us/library/windows/desktop/ms682583%28v=vs.85%29.aspx : (optional) DllMain entry point
BOOL WINAPI DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
}
然后编译/链接
cl /D_USRDLL /D_WINDLL SayHello.cpp /LD /link /OUT:SayHello.dll
/LD告诉链接器构建DLL并使用/MT,请参阅。(通过OUT:parameter,您可以更改.dll的名称;这里是默认名称,仅用于演示。如果不使用它,您还可以跳过/link参数,因为不再有链接器参数。)
匹配dll的运行时库设置,创建一个(main.cpp有一个
int main()
)并链接SayHello的存根库(而不是使用/)我将VolkerK的答案标记为正确,因为它包含了一些非常值得一读的其他重要Windows dll API详细信息,但我想总结一下,根据Igor Tandetnik和VolkerK的评论,在最简单的示例中,动态链接可以实现的最小变化
- 在DLL中至少要导出一个函数之前添加宏
,这是必不可少的,否则库编译命令将不会创建导入库来指示哪些函数可用于动态链接\uuuu declspec(dllexport)
- 第二个“lib say_hello.obj”是完全错误的,因为DLL编译命令将正确地生成say_hello.lib(而该lib命令只会生成一个静态库并最终覆盖第一个命令)
void say_hello();
int main()
{
say_hello();
return 0;
}
#include <stdio.h>
void say_hello()
{
printf("Hello DLL World!");
}
void say_hello();
int main()
{
say_hello();
return 0;
}
#include <stdio.h>
__declspec(dllexport) void say_hello()
{
printf("Hello DLL World!");
}
打招呼。cpp
void say_hello();
int main()
{
say_hello();
return 0;
}
#include <stdio.h>
void say_hello()
{
printf("Hello DLL World!");
}
void say_hello();
int main()
{
say_hello();
return 0;
}
#include <stdio.h>
__declspec(dllexport) void say_hello()
{
printf("Hello DLL World!");
}
cl say_hello.cpp/LD
应在.lib文件中生成DLL和导入库。随后的lib
命令将用静态库覆盖前面提到的导入库。别那么做。另一个问题是名称需要通过DEF文件或\uuu declspec(dllexport)
从DLL显式导出。如前所述,您没有导出任何内容,因此没有实际链接的内容。啊,是的。。。第一步cl say_hello.cpp/LD
的控制台输出似乎表明创建了“/implib:say_hello.lib”,但我只看到目录中生成的say_hello.obj
和say_hello.dll
。是否需要传递一些其他标志来告诉它不要清理导入库?啊,我明白了,为要导出的函数添加前缀的\u declspec(dllexport)
宏是至关重要的,因为如果没有它,cl.exe会在完成后立即删除导入库文件say_hello.lib
。是的,因为没有什么可导入的;-)Doh,混淆了第二个cl.exe命令的编译器/链接器参数。自我提示:先测试,然后发布。