【问题标题】:How to define entry point in C++/CLI DLL with command line argument /ENTRY如何使用命令行参数 /ENTRY 在 C++/CLI DLL 中定义入口点
【发布时间】:2021-11-24 18:46:08
【问题描述】:

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

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

我创建了支持 /CLR 的托管 C++ DLL,并将主函数的名称替换为“开始”:

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;
}

【问题讨论】:

  • DLL 的入口点一直是,现在仍然是 C++/CLI 程序集,一个名为“DllMain”的函数。谁的签名看起来不像你的 Start() 方法。链接器没有警告您的错误。它的结局很糟糕,你没有得到字符串,返回值很重要,它会被多次调用。
  • @Hans Passant:你是对的,我试图以两种方式编译这个项目 - 作为 DLL 或 EXE,如果输出是 EXE 文件,则可以编译这个问题的第一个版本中提到的函数,如果我尝试将其编译为 DLL,它会通知我函数的签名是错误的,因此我将其更正为 DLL 的函数。
  • 这仍然不是 DLL 入口点的正确签名。此外,在托管程序集中指定/ENTRY 是一个非常糟糕的主意,因为现在C++ 运行时库中的所有.NET Framework 支持代码都不会被执行。只需保留库提供的入口点,并提供一个名为 DllMain 的函数,库入口点将调用该函数。

标签: dll c++-cli


【解决方案1】:

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

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

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

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

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

【讨论】:

  • 谢谢,这是有道理的,不过,无论如何我想提一下,我能够将新的 C# WinForms 项目添加到我的解决方案中,并从我的自定义入口点调用它,所以我认为尽管建议使用 DllMainCRTStartup 中的代码,但它并不那么重要。
  • @SkyScanner:我对一些具体的后果添加了更多解释。
【解决方案2】:

我傻了。选项 /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"

【讨论】:

    猜你喜欢
    • 2020-12-16
    • 1970-01-01
    • 1970-01-01
    • 2010-11-25
    • 2016-02-17
    • 2013-01-13
    • 2021-05-24
    • 1970-01-01
    • 2012-06-15
    相关资源
    最近更新 更多