Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/130.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在MinGW中导入内联函数_C++_Dll_Linker_Mingw_Inline - Fatal编程技术网

C++ 在MinGW中导入内联函数

C++ 在MinGW中导入内联函数,c++,dll,linker,mingw,inline,C++,Dll,Linker,Mingw,Inline,我正在使用一个共享库,它在头文件中定义内联函数 这里是一个简化的测试用例,正如链接到库的编译单元所看到的(对于库看到的版本,只需将dllimport替换为dllexport) 编译此文件时会发出警告: 警告:在没有dllimport的情况下重新声明了“int MyClass::myFunc1()” 使用dll链接引用后的属性[默认启用] 请注意,函数的定义顺序很重要,因为将myFunc1的定义放在myFunc2的定义之前不会导致任何警告 注意,此代码在VisualC++中没有警告的情况下编译。这

我正在使用一个共享库,它在头文件中定义内联函数

这里是一个简化的测试用例,正如链接到库的编译单元所看到的(对于库看到的版本,只需将
dllimport
替换为
dllexport

编译此文件时会发出警告:

警告:在没有dllimport的情况下重新声明了“int MyClass::myFunc1()” 使用dll链接引用后的属性[默认启用]

请注意,函数的定义顺序很重要,因为将
myFunc1
的定义放在
myFunc2
的定义之前不会导致任何警告

注意,此代码在VisualC++中没有警告的情况下编译。这些警告至少针对MinGW,可能针对GCC。编辑:我想到,我可能必须验证该警告是否未被项目设置的某个标志所禁止

我的问题是:

  • 为什么会有这种行为
  • 在类声明中将
    myFunc1
    声明为
    inline
    ,可以解决此问题。为什么呢?这也违反了做事的原则
  • 是否有其他(更好的?)方法来解决此问题

    • 问题的出现是因为dllimport的工作方式有一些魔力,这通常意味着您只需要在第一次声明时使用它

      基本上,当您将函数声明为dllimport,然后使用除dllimport之外的相同声明重新声明该函数时,第二个声明隐式地获取dllimport。如果重新声明不相同,则不会获得隐式dllimport

      这里发生的事情是,首先将函数声明为dllimport/non-inline,然后将其声明为non-dllimport/inline。在第一个声明中添加内联可以解决问题,因为第二个声明将隐式地成为dllimport。或者,在第二个声明中添加一个
      \uu declspec(dllimport)
      应该可以解决这个问题

      请注意,对定义重新排序会消除警告,因为警告是关于在重新声明之前使用它。使用重新排序时,您在重新声明之前不再使用它,因此不会收到任何警告,尽管它将使用非dllimport版本(即,它永远不会使用dll中函数的版本)


      另外请注意,使用内嵌dllimport是危险的。根据dll构建的任何程序可能在某些位置使用内联函数,而在其他位置使用非内联函数(来自dll)。即使这两个函数现在是相同的,dll的未来版本也可能会更改,并具有不同的实现。在这一点上,如果使用新版本的dll运行,旧程序可能会开始出现错误。

      有关Chris Dodd答案的更多信息:

      我使用和MinGW-w64 7.2.0进行了测试;在这两种情况下,启用优化后,从
      myFunc2
      调用
      myFunc1()
      将解析为内联版本,尽管出现警告。即使
      myFunc1
      的主体被移动到
      main()
      的下方

      因此,我的初步结论是,忽略这一警告是安全的


      为了实现干净的编译,在MinGW-w64中唯一有效的方法是将类定义中的函数声明标记为
      inline
      。编译器不允许将
      \uu declspec(dllimport)
      应用于类外函数定义


      我无法确定g++是否有一个警告标志专门禁用此警告。

      实际上,在第二个声明中添加一个
      \u declspec(dllimport)
      会得到一个
      警告:内联函数“int MyClass::myFunc1()”声明为dllimport:attribute ignored[-Wattributes]
      (对于
      myFunc2
      )也是一样。这也有点令人困惑,但我假设所有这些都是任意的。对于C来说显然不是这样。代码片段
      \u declspec(dllimport)void f(void);void f(void);
      给出了警告:
      警告:“f”在没有dllimport属性的情况下重新声明:先前的dllimport被忽略了。为什么?
      
      class __declspec(dllimport) MyClass {
      public:
          int myFunc2();
          int myFunc1();
      };
      
      inline int MyClass::myFunc2(void) {
          return myFunc1();
      }
      
      inline int MyClass::myFunc1(void) {
          return 0;
      }