开发者

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

开发者 https://www.devze.com 2023-04-03 16:43 出处:网络
Im trying to get a value of a string exported by an unmanaged dll. The string in the dll is declared as

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 = Cha开发者_StackOverflow中文版rSet.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);


You have to use Marshal.PtrToStringAnsi() here.

"Auto" means "operating system default". With Windows 98 and ME on the endangered species list, that's very likely Unicode on your machine. Your string isn't const wchar_t*.


Here is my solution; checked-it, it works.

IntPtr procAddress = GetProcAddress(lib, "_Version");
IntPtr verAddress = Marshal.ReadIntPtr(procAddress);
var ver2 = Marshal.PtrToStringAnsi(verAddress);


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

精彩评论

暂无评论...
验证码 换一张
取 消