Search code examples
c++.netunmanageddllexport

Robert Giesecke's Unmanaged Exports


I'm trying to get an DllExport from vb.net to unmanaged c++ working.

I'm using Robert Giesecke's Unmanaged Exports with Visual Studio 2012 and tried to follow this very helpful hints. I copy the dlls from the .Net project by an post build action in the directory where my *.cpp and *.h files reside.

I checked my dll with dumpbin /EXPORTS Nugget.Discovery.dll and it tells me that there are exports:

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

But if I try to import it in the cpp file with

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

I get one IntelliSense error and one error after I try to compile:

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.

Any idea what I'm doing wrong?

Best regards! Stefan


Solution

  • Ok, thanks to Hans Passant I came to this solution:

    This is my code on the managed side:

    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
    

    Interesting is, that I cannot call functions that are marked with <DllExport> from managed code (even if they are Public).

    And this is the code on the native side:

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

    Are there any other better solutions?

    Ciao! Stefan