3

我正在尝试从 vb.net 获取 DllExport 到非托管 c++ 工作。

我正在使用Robert Giesecke 的 Unmanaged Exports with Visual Studio 2012 并尝试遵循这个非常有用的提示。我通过在我的 *.cpp 和 *.h 文件所在的目录中的构建后操作从 .Net 项目中复制 dll。

我检查了我的 dll,dumpbin /EXPORTS Nugget.Discovery.dll它告诉我有出口:

File Type: DLL
Section contains the following exports for \Nugget.Discovery.dll
00000000 characteristics
52554A05 time date stamp Wed Oct 09 14:20:21 2013
    0.00 version
       0 ordinal base
       2 number of functions
       2 number of names
ordinal hint RVA      name
      0    0 0000532E StartAnnouncing
      1    1 0000533E StopAnnouncing
Summary
    2000 .reloc
    4000 .rsrc
    2000 .sdata
    4000 .text

但是如果我尝试将它导入到 cpp 文件中

#import "Nugget.Discovery.dll" 
   void StartAnnouncing(int serial);

我在尝试编译后收到一个 IntelliSense 错误和一个错误:

IntelliSense: cannot open source file "Debug/Nugget.Discovery.tlh"
error C1083: Cannot open type library file: 'nugget.discovery.dll': Fehler beim Laden der Typbibliothek/DLL.

知道我做错了什么吗?

最好的祝福!斯特凡

4

2 回答 2

3

作为 DllExport 的一部分,会生成一个 .lib 文件。您可以使用它来使用普通的 C++ 链接器,而不是 LoadLibrary/GetProcAddress。

从您发布的托管代码开始,在本机端:

extern CALLBACK void StartAnnouncingType(int serial);
extern CALLBACK int TestType(void);

int _tmain(int argc, _TCHAR* argv[])
{
    int test = TestPtr();
    StartAnnouncingPtr(1);
}

在非托管项目的设置中,添加Nugget.Discovery.lib到项目属性:配置属性->链接器->输入。并将 Nugget.Discovery.dll 复制到输出目录。

于 2014-01-24T10:09:28.590 回答
2

好的,感谢Hans Passant ,我找到了这个解决方案:

这是我在托管端的代码:

Imports System.Runtime.InteropServices
Imports RGiesecke.DllExport

Public NotInheritable Class Beacon

Private Sub New()
End Sub

Private Shared _nuggetAnnouncement As NuggetAnnouncement

' ReSharper disable UnusedMember.Local
''' <remarks>Cannot be called from managed code!</remarks>
<DllExport("StartAnnouncing", CallingConvention.StdCall)>
Private Shared Sub StartAnnouncingNative(serial As Integer)
    StartAnnouncing(serial)
End Sub

''' <remarks>Cannot be called from managed code!</remarks>
<DllExport("Test", CallingConvention.StdCall)>
Private Shared Function TestNative() As Integer
    Return Test()
End Function
' ReSharper restore UnusedMember.Local

Public Shared Sub StartAnnouncing(serial As Integer)
    'do something
End Sub

Public Shared Function Test() As Integer
    Return 42
End Function

End Class

有趣的是,我不能<DllExport>从托管代码中调用标记有的函数(即使它们是公共的)。

这是本机端的代码:

typedef void (CALLBACK* StartAnnouncingType)(int);
typedef int (CALLBACK* TestType)(void);

int _tmain(int argc, _TCHAR* argv[])
{
HINSTANCE dllHandle = NULL;   
StartAnnouncingType  StartAnnouncingPtr = NULL;
TestType TestPtr = NULL;
wchar_t dllNameWide[64];
int size = mbstowcs(dllNameWide, "Nugget.Discovery.dll", sizeof(dllNameWide));
dllHandle = LoadLibrary(dllNameWide);
if (NULL != dllHandle) 
{ 
  //Get pointer to our function using GetProcAddress:
  StartAnnouncingPtr = (StartAnnouncingType)GetProcAddress(dllHandle,"StartAnnouncing");
  TestPtr = (TestType)GetProcAddress(dllHandle,"Test");
  int test;
  if (NULL != TestPtr) test = TestPtr();
  int serial = 1;
  if (NULL != StartAnnouncingPtr) StartAnnouncingPtr(1);
  //Free the library:
  FreeLibrary(dllHandle);    
}
}

还有其他更好的解决方案吗?

再见!斯特凡

于 2013-10-10T08:40:18.557 回答