C# 获取.NET中非托管dll导出的char*的值

C# 获取.NET中非托管dll导出的char*的值,c#,.net,pinvoke,C#,.net,Pinvoke,我正在尝试获取由非托管dll导出的字符串的值 dll中的字符串声明为 extern "C" __declspec(dllexport) const char* _Version = "0.1"; 下面是我用来获取值的代码。我通过调用GetProcAddress获取变量的地址,但是Marshal.PtrToStringAuto返回垃圾 怎么了 public string GetDllVersion() { IntPtr lib = LoadLibrary(

我正在尝试获取由非托管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);

这里必须使用Marshal.PtrToStringAnsi()


“自动”表示“操作系统默认”。由于Windows 98和我被列入濒危物种名单,您的计算机上很可能使用Unicode。您的字符串不是常量wchar\u t*

通过从GetProcAddress取消对指针的引用修复了此问题:

procAddress = Marshal.ReadIntPtr(GetProcAddress(lib, "_Version"));
还更改了根据Hans Passant的建议读取字符串的方式(其他答案):


这是我的解决方案;检查过了,它工作了

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

我觉得有点复杂。IntPtr procAddress中返回的地址是指针,因此我必须取消对它的引用以获取值。例如,在上一次运行时,我在procAddress中得到0x092c7000,它指向0x092c553c,而0x092c553c又保存了值。。。不管怎么说,只是改成PtrToStringAnsi并没有帮助,这是无可争辩的。从DLL导出数据是非常少见的,不确切地知道规则是什么。使用Marshal.ReadIntPtr()。+1“从DLL导出数据是非常少见的。”我想您从未享受过针对Python C API编写代码的乐趣!;-)已经知道了,看看我自己的答案。尽管如此,我还是投了赞成票
IntPtr procAddress = GetProcAddress(lib, "_Version");
IntPtr verAddress = Marshal.ReadIntPtr(procAddress);
var ver2 = Marshal.PtrToStringAnsi(verAddress);