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