如何使用命令行参数/ ENTRY在C ++ / CLI DLL中定义入口点

时间:2014-10-16 22:53:25

标签: dll c++-cli

cl.exe中有一个选项可以使用命令行属性/ ENTRY在DLL中定义自定义入口点。不幸的是,它没有提供如何使用它的示例。

http://msdn.microsoft.com/en-us/library/f9t8842e%28v=vs.100%29.aspx

我创建了支持/ CLR的托管C ++ DLL,并使用" Start"替换了main函数的名称:

int Start(int argc, char *argv[])
{
    return 0;
}

然后我尝试使用此BAT命令从命令行编译此DLL:

"c:\Program Files\Microsoft Visual Studio 12.0\VC\bin\cl.exe" ^
    /clr /Fo /Z7 /D "NDEBUG" ^
    /ENTRY:Start ^
    "..\Links\Links.cpp"

不幸的是,我收到了这个错误:

LNK1561: Entry point must be defined

问题:我应该准确传递什么作为/ ENTRY参数?

修改:正如Hans'下面的注释,函数曾经是DLL中的一个入口点,需要有另一个签名,所以我在上面的例子中进行了更正。下面给出的函数是EXE文件的入口点的示例,特别是因为它在其参数中具有托管类型。

int Start(array<String ^> ^ argc)
{
    return 0;
}

2 个答案:

答案 0 :(得分:2)

在托管程序集上指定/ENTRY是一个非常糟糕的主意,因为现在不会执行C ++运行时库中的所有.NET Framework支持代码。全局C ++对象的初始化器也不会有机会运行。并且您可能会在工作线程上出现内存泄漏,因为C ++运行时库足够智能,可以在需要时执行线程局部初始化,但由于它没有接收到线程分离事件,因此无法清理。另一方面,C ++ / CLI程序集总是动态链接到运行时DLL,因此至少该库DllMain将接收线程通知,并且运行时本身使用的资源将不会泄漏。

只留下库提供的DllMainCRTStartup入口点,并提供一个名为DllMain的函数,库入口点将调用该函数。

关于C ++ / CLI托管程序集中的初始化代码,MSDN上有大量文档:

其中一个重要的事情是,DllMain签名(再次,它不是实际的入口点,它是从库提供的入口点调用的),是

BOOL WINAPI DllMain(
  _In_  HINSTANCE hinstDLL,
  _In_  DWORD fdwReason,
  _In_  LPVOID lpvReserved
);

答案 1 :(得分:0)

傻傻的我。 Option / ENTRY是link.exe的参数,而不是cl.exe的参数

使用以下BAT脚本,我可以强制我的程序集具有自定义入口点。唯一的问题是,在这种情况下,链接器需要使用/ SUBSYSTEM选项直接设置项目类型。

"c:\Program Files\Microsoft Visual Studio 12.0\VC\bin\link.exe" ^
    /DLL /ENTRY:Start ^
    /SUBSYSTEM:CONSOLE ^
    /WX ^
    /OUT:Links.dll ^
    "Links.obj"