获取.net中非托管dll导出的char*的值

本文关键字:char 的值 dll net 获取 | 更新日期: 2023-09-27 18:07:52

我试图获得由非托管dll导出的字符串值。

dll中的字符串声明为
extern "C" __declspec(dllexport) const char* _Version = "0.1";

我用来获取值的代码如下。我从对GetProcAddress的调用中获得变量的地址,但Marshal.PtrToStringAuto返回垃圾…

什么错了吗?

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

获取.net中非托管dll导出的char*的值

这里必须使用Marshal.PtrToStringAnsi()

"Auto"表示"操作系统默认值"。Windows 98和ME都在濒危物种列表中,这很可能是您机器上的Unicode。你的字符串不是const wchar_t*.

这是我的解决方案;检查过了,可以了。

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

通过从GetProcAddress:

解引用指针修复此问题
procAddress = Marshal.ReadIntPtr(GetProcAddress(lib, "_Version"));

根据Hans Passant的建议(另一个答案)也改变了读取字符串的方式:

var ver2 = Marshal.PtrToStringAnsi(procAddress);