在MinGW的导入内联函数(Importing inline functions in MinGW)

2019-06-26 09:25发布

我使用,在其头部定义内联函数的共享库。

下面是一个简化的测试情况下,由编译单元连接到库所看到(对于由库看到的版本,只需更换dllimportdllexport )。

class __declspec(dllimport) MyClass {
public:
    int myFunc2();
    int myFunc1();
};

inline int MyClass::myFunc2(void) {
    return myFunc1();
}

inline int MyClass::myFunc1(void) {
    return 0;
}

编译这给了警告:

警告:“诠释MyClass的:: myFunc1()”没有DllImport属性与DLL链接被引用后重新声明[默认启用]

请注意,该功能定义的顺序是非常重要的,因为推杆的定义myFunc1的定义之前myFunc2在没有任何警告的结果。

注意,这个代码在编译时没有在Visual C ++警告。 这些警告是特定至少MinGW的,也许在一般的GCC。 编辑:它来到我的脑海里,我可能要验证是否警告不是由项目设置的标志之一抑制。

我的问题是,那么:

  • 为什么这种行为?
  • 声明myFunc1作为inline类声明中解决了这个问题。 这是为什么 ? 这也是对推荐的方式做事。
  • 难道还有其他(更好?)的方式来解决这个问题?

Answer 1:

这个问题是有关的,因为在dllimport的作品通常意味着你只需要在第一个声明的方式一些魔术。

基本上,当你声明一个函数为dllimport再后来用除dllimport的相同的声明重新声明功能,第二个声明隐含得到dllimport的。 如果重新声明是不相同的,它不会隐dllimport的。

所以会发生什么这里是你首先声明函数为dllimport /非内联,然后宣布它作为非dllimport的/直列。 添加一个内联到所述第一声明可以解决问题,作为第二然后变得隐含dllimport的。 可替换地,增加一个__declspec(dllimport)到所述第二声明应该解决这个问题。

需要注意的是重新排序的定义摆脱了警告,因为警告是关于重新声明之前使用它。 随着重排,你已不再是重复声明之前使用它,所以你得到任何警告,但它会使用非dllimport的版本(即,它不会使用的功能从DLL版本)。

还要注意,使用内联dllimport的是危险的。 对建成的dll的任何程序可以使用内联函数在其他一些地方和非内联函数(从DLL)。 即使这两个功能是相同的现在,DLL的未来版本可能会发生变化,并有不同的实现。 在这一点旧的程序可能会开始如果与该DLL的新版本上运行失常。



Answer 2:

更多信息,多德的回答是:

我用测试MSVC 2017和MinGW-W64 7.2.0; 在这两种情况下,启用了优化,通话myFunc1()myFunc2解析为内嵌版本,尽管警告。 即使身体myFunc1被移动到下面main()

所以,我的初步结论是,它是安全的忽略此警告。


在全新的编译的利益,这似乎是在MinGW的-W64工作的唯一方法是将类标记定义中的函数声明inline 。 所述编译器不允许施加__declspec(dllimport)以外的类中的函数定义。

我一直无法确定是否存在对G ++这将明确禁用该警告的警告标志。



文章来源: Importing inline functions in MinGW