C # Не удается найти точку входа в неразборчивую библиотеку C

#c# #c #c

#c# #c #c

Вопрос:

Я получаю сообщение об ошибке «Не удается найти точку входа с именем ‘foo’ в DLL ‘example.dll ‘».

Я использовал depends.exe и DUMPBIN.exe . Функция есть, и ее имя не перепутано.

Вы видите в этом что-то особенно неправильное?

Вот код C .

 //example.cpp
//Using Multibyte Char Set. (if that matters)
//Edit: I can not change this code.
extern "C" _declspec(dllexport) int foo(const char *name)
{
...
}
  

Вот код C #.

 //importing.cs
public static class ImportClass
{
[DllImport("example.dll")]
public static extern int foo(string name)
}
  

Я не могу изменить C , он был предоставлен внешним источником, который запрещает это.
Заранее спасибо.

Комментарии:

1. измените спецификацию с _declspec на __stdcall

2. Я забыл упомянуть. Я не могу изменить ни один код C . Он был предоставлен мне из внешнего источника, который запрещает вмешательство в него.

3. Тогда вы ничего не сможете сделать, проблема в dll.

4. Человек.. Это очень плохо. Возможно ли для меня создать оболочку C для вызова функции из библиотеки dll, а затем использовать _stdcall в оболочке?

5. Вы определенно можете обернуть C в свой собственный код C с требуемым соглашением о вызовах, если не найдете решения с помощью DllImport.

Ответ №1:

Возможно, вы стали жертвой Name Mangling here. Искажение имен в Википедии

Сначала используйте dumpbin.exe для перечисления определений, экспортируемых вашей dll.

 eg: `dumpbin.exe /EXPORTS example.dll`
  

Проверьте имя экспортируемой функции.

Затем используйте импорт DLL следующим образом:

 [DllImport("example.dll", EntryPoint = @"TheNameFrom DumpBin goes here")]
  

Возможно, вы также захотите посмотреть CallingConvention атрибут.

Комментарии:

1. его код на c говорит extern «C» (что отключает обработку имен c )

2. Да, так говорится в большинстве документов, но я видел на практике, что компиляторы обычно добавляют к именам функций что-то. например: an underscore , или слегка измените их, изменив регистр имен. Обычно лучше проверять использование dumpbin ошибок точки входа.

3. Даже Dumpbin.exe показывает, что они не перепутаны. Я собираюсь использовать технику обертки и сообщить о результатах.

Ответ №2:

Согласно MSDN, соглашение о вызове метода, импортируемого с помощью импорта DLL, по умолчанию __stdcall , означает, что он не сможет найти ваш __declspec метод. Попробуйте изменение его на __stdcall или создание вашего DllImport указывает CallingConvention.Cdecl

Как уже упоминалось, искажение имен также может быть проблемой, если предположить, что вызываемая библиотека не объявляла метод с EXPORTS помощью оператора.

Ответ №3:

Не используйте повторяющиеся имена файлов.

Моя программа загружала неправильную «example.dll «; тот, у которого не было foo().

Я действительно сожалею обо всех проблемах, ребята.