Search code examples
c#.netpinvoke

Getting value of a char* exported by unmanaged dll in .NET


Im trying to get a value of a string exported by an unmanaged dll.

The string in the dll is declared as

extern "C" __declspec(dllexport) const char* _Version = "0.1";

The code I'm using to get the value is below. I get the address for the variable from the call to GetProcAddress but Marshal.PtrToStringAuto returns garbage...

Whats wrong?

    public string GetDllVersion()
    {
            IntPtr lib = LoadLibrary(@"some.dll");
            if(lib == IntPtr.Zero)
                    throw new Win32Exception(Marshal.GetLastWin32Error());

            IntPtr procAddress = GetProcAddress(lib, "_Version");
            var ver2 = Marshal.PtrToStringAuto(procAddress);

            if(!FreeLibrary(lib))
                    throw new Win32Exception(Marshal.GetLastWin32Error());
            return ver2;
    }

    [DllImport("kernel32", SetLastError = true, CharSet = CharSet.Unicode)]
    static extern IntPtr LoadLibrary(string lpFileName);

    [DllImport("kernel32", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)]
    static extern IntPtr GetProcAddress(IntPtr hModule, string procName);

    [DllImport("kernel32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool FreeLibrary(IntPtr hModule);

Solution

  • Fixed this by dereferencing the pointer from GetProcAddress:

    procAddress = Marshal.ReadIntPtr(GetProcAddress(lib, "_Version"));
    

    Also changed the way to read the string per suggestion from Hans Passant (other answer):

    var ver2 = Marshal.PtrToStringAnsi(procAddress);