需要的DLL入口点问题/建议

dll entry point question/advice needed

本文关键字:问题 建议 入口 DLL      更新时间:2023-10-16

我有一个动态的c++代码库,它是跨平台的,大部分都是本地的c++。然后我从我的主exe中使用这个动态库。到目前为止,在OSX上使用gcc一切都很好。现在我在windows上,我对我应该使用什么方法来进入dll感到困惑。目前我没有DllMain函数,因为这在gcc中是不需要的(据我所知)。我最初的测试工作,但检查显示,奇怪的是,我的一个类构造函数在dll加载时被调用,所以我认为我需要在windows上做更多的事情。我也是:

  • 添加DllMain函数?
  • 我可以安全地使用无条目编译器选项吗?

当我做上述任何一件事时,我就会开始收到类似于"。

我已经阅读了这篇文章,但是任何建议和最好的前进方式的清晰度将是非常感激的。

我脑子里有点模糊,不知道该怎么做。

根据. crt错误,您肯定需要一个DllMain函数。对于大多数Windows编译器,将自动为您提供一个dlmain,因此您不需要自己编写一个。根据你问题的其他部分,你似乎最有可能使用Visual c++,它的CRT确实为你提供了一个DllMain。所以当你需要一个DllMain时,你不需要为它写代码。

默认的VC CRT DllMain用于初始化所讨论的DLL的CRT,并初始化DLL提供的所有静态/全局变量。

Unix和Windows上的DLL模型有很大的不同,你应该认为每个DLL都有一个更"私有"的状态集。但是,如果所有dll都选择使用相同版本的CRT dll,那么其中一些状态将被共享。

因为CRT为您提供了一个dlmain,所以您不应该在链接器上抛出/noentry。

. crt部分存在错误(你必须通过抛出/noentry看到)告诉你,你需要一个DllMain,因为你在你的DLL中有一个或多个对象需要静态初始化。

Martyn

如果它只是一个库,那么NOENTRY应该足够了。DllMain是用来控制与DLL一起发生的事件(即附加,分离等)。

您可以(稍微)更改代码以避免除main之外的所有入口点。本质上,如果您在函数外部定义了任何变量(全局的,但不是静态链接的),请将它们包装在函数调用中。使用经常被遗忘的静态函数变量。例如,修改全局声明

SomeType var_name;

:

SomeType & var_name(){static SomeType var; return var;}

同样,您可以通过以下方式更改静态类实例变量:

struct Container{
    Container();
    static Container instance;
};
Container Container::instance;

:

struct Container{
    Container();
    static Container & instance();
};
Container & Container::instance(){
    static Container var;
    return var;
}

这本质上是一个单例,但如果您第一次访问实例将从多线程环境中,则可能存在一些并发性问题。实际上,需要记住的是,与全局定义变量不同,静态局部定义变量将在函数第一次调用时初始化。