C# GetProcAddress Возвращает Ноль
по какой-то причине, когда мое приложение C# .NET 2.0 делает вызов GetProcAddress
Он всегда возвращает ноль.
public class MyClass
{
internal static class UnsafeNativeMethods
{
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
internal static extern IntPtr LoadLibrary(string lpFileName);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
internal static extern bool SetDllDirectory(string lpPathName);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
internal static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
}
private void MyFunc()
{
IntPtr _dllHandle;
IntPtr _fptr;
string _fullPath = ".mydll.dll";
string _procName = "MyDllFunc";
_dllHandle = UnsafeNativeMethods.LoadLibrary(_fullPath);
_fptr = UnsafeNativeMethods.GetProcAddress(_dllHandle, _procName); // <-- Always returns zero.
}
}
Я уверен, что имя функции написано правильно, и _fullPath
- это, вероятно, правильно, потому что _dllHandle
всегда присваивается ненулевое значение. Любое понимание можно обеспечить оценили. Спасибо.
4 ответов
GetProcAddress поставляется только в вкусе ANSI, поэтому мы помогаем среде выполнения, говоря ей всегда использовать ANSI при маршалировании строкового параметра. Мы также запрещаем среде выполнения искать несуществующий GetProcAddressA, потому что по умолчанию для C# установить ExactSpelling в false.
вам действительно нужно добавить некоторую проверку ошибок. По крайней мере, проверьте, если _dllHandle != Тип IntPtr.Нуль. Кроме того, в зависимости от текущего рабочего каталога опасно использовать сборку.GetEntryAssembly().Месте, чтобы получить полное имя пути.
имя функции, вероятно, неправильно. Экспорт, как правило, украшен, как _MyDllFunc или _MyDllFunc@4. Более дико, если он был скомпилирован компилятором с++. Используйте Dumpbin.exe / экспорт в вашей DLL, чтобы увидеть реальные имена.
вернуться к ошибке обработка, используйте SetLastWin32Error в атрибуте [DllImport]. Бросьте Win32Exception, если функция возвращает false или IntPtr.Нуль.
Edit: я вижу реальную проблему. Использование CharSet.Авто для GetProcAddress () неверно. Очень не повезло, это как раз о только функция Windows API, которая имеет только версию ANSI. Вы должны использовать CharSet.кодировка ANSI. Хорошим местом для получения правильных деклараций [DllImport] является pinvoke.net
вы не показали, как вы экспортируете функцию из DLL, но я подозреваю, что проблема в том, что экспортированное имя не то, что вы вещь. Вы можете запустить dumpbin /exports mydll.dll
просмотреть экспорта ДЛЛ для проверки имени.
Если вы покажете фрагмент кода экспорта, я мог бы предоставить более прямые советы. Вы можете попробовать украсить экспортированную функцию с помощью extern "C"
чтобы исключить искажение имени в качестве теста.
ваша экспорта .DEF-файл для DLL соответствует входу здесь? Вы можете использовать dumpbin
чтобы узнать, что экспортируется, за другие ответы здесь.
что такое основная ошибка Win32 на GetProcAddress()
, per GetLastError()
?
вы можете попробовать это в собственном коде, чтобы сначала выработать правильные входные данные без дополнительного багажа P / Invoke.