C # обертка c ++ dll; «Ошибка проверки времени выполнения № 0 - значение ESP не было должным образом сохранено при вызове функции». ошибка - PullRequest
3 голосов
/ 12 марта 2010

Вот код на C ++ dll:

extern "C" _declspec(dllexport) int testDelegate(int (*addFunction)(int, int), int a, int b)
{
    int res = addFunction(a, b);
    return res;
}

и вот код в C #:

public delegate int AddIntegersDelegate(int number1, int number2);

public static int AddIntegers(int a, int b)
{
  return a + b;
}

[DllImport("tester.dll", SetLastError = true)]
public static extern int testDelegate(AddIntegersDelegate callBackProc, int a, int b);

public static void Main(string[] args)
{
  int result = testDelegate(AddIntegers, 4, 5);
  Console.WriteLine("Code returned:" + result.ToString());
}

Когда я запускаю это маленькое приложение, я получаю сообщение из заголовка этого поста. Может кто-нибудь помочь, пожалуйста?

Заранее спасибо,

D

Ответы [ 3 ]

11 голосов
/ 12 марта 2010

Адам прав, у вас несоответствие соглашения о вызовах в 32-разрядной версии Windows. По умолчанию указатель функции равен __cdecl, а объявление делегата - CallingConvention.StdCall. Несоответствие приводит к тому, что указатель стека не восстанавливается должным образом при возврате вызова делегата, вызывая диагностику в отладочной сборке кода C / C ++.

Чтобы исправить это на стороне C / C ++:

typedef int (__stdcall * Callback)(int, int);

extern "C" _declspec(dllexport) int testDelegate(Callback addFunction, int a, int b)
{
    int res = addFunction(a, b);
    return res;
}

Чтобы исправить это на стороне C #:

    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
    public delegate int AddIntegersDelegate(int number1, int number2);
3 голосов
/ 12 марта 2010

Аргумент указателя функции testDelegate должен быть помечен __stdcall, в противном случае его вызов повредит стек (поскольку он использует разные соглашения о вызовах.)

0 голосов
/ 12 марта 2010

Обычно это означает «несоответствие интерфейса»: объявление, используемое для компиляции клиента, отличается от фактической версии dll.

...