Получение значения char *, экспортируемого неуправляемой DLL в .NET - PullRequest
5 голосов
/ 08 сентября 2011

Я пытаюсь получить значение строки, экспортируемой неуправляемой 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);

Ответы [ 3 ]

4 голосов
/ 08 сентября 2011

Вот мое решение; проверил-все работает.

IntPtr procAddress = GetProcAddress(lib, "_Version");
IntPtr verAddress = Marshal.ReadIntPtr(procAddress);
var ver2 = Marshal.PtrToStringAnsi(verAddress);
4 голосов
/ 08 сентября 2011

Вы должны использовать Marshal.PtrToStringAnsi () здесь.

«Авто» означает «операционная система по умолчанию». С Windows 98 и ME в списке исчезающих видов, это очень вероятно, Unicode на вашем компьютере. Ваша строка не постоянная wchar_t *.

3 голосов
/ 08 сентября 2011

Исправлено это путем разыменования указателя из GetProcAddress:

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

Также изменен способ чтения строки в соответствии с предложением Ханса Пассанта (другой ответ):

var ver2 = Marshal.PtrToStringAnsi(procAddress);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...