c # — Сбой в режиме отладки (F5) при вызове собственного метода C ++

Я пытаюсь вызвать метод C ++ с помощью LoadLibrary, GetProcAddress и GetDelegateForFunctionPointer.

Все в порядке (в выпуске и отладке), если я запускаю приложение .NET 4.0 (Ctrl + F5). Но когда я запускаю режим отладки (F5), происходит сбой программы при вызове метода C ++.

.Cpp:

#include "PointEntree.h"#include <stdio.h>
extern "C" __declspec( dllexport ) int Test1(int a)
{
printf("coucou\n");
return 0;
}

.H:

extern "C" __declspec( dllexport ) int Test1(int);

.Cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace NETProgram
{
static class NativeMethods
{
[DllImport("kernel32.dll")]
public static extern IntPtr LoadLibrary(string dllToLoad);

[DllImport("kernel32.dll")]
public static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName);

[DllImport("kernel32.dll")]
public static extern bool FreeLibrary(IntPtr hModule);
}

class Program
{
delegate int Bambou_Test1(int i);

static void Main(string[] args)
{
IntPtr pDll = NativeMethods.LoadLibrary(@"E:\Dev\C#\ImportC++\Bambou\Release\Bambou.dll");
IntPtr pAddressOfFunctionToCall = NativeMethods.GetProcAddress(pDll, "Test1");

Bambou_Test1 method = (Bambou_Test1)Marshal.GetDelegateForFunctionPointer(pAddressOfFunctionToCall, typeof(Bambou_Test1));
method.Invoke(12);
}
}
}

Если я использую классический импорт DLL, как показано ниже, он работает, но это не то, чего я хочу достичь:

[DllImport(@"E:\Dev\C#\ImportC++\Bambou\Debug\Bambou.dll", EntryPoint = "Test1",  CallingConvention=CallingConvention.Cdecl)]
public static extern int Test1(int a);

Если у кого-то есть идеи, было бы здорово!

1

Решение

P / Invoke был в основном предназначен для взаимодействия с Windows API, поэтому в StdCall соглашение по умолчанию. C использует Cdecl соглашение по умолчанию. Вам нужно изменить одну из сторон, чтобы явно указать соглашение о вызовах, чтобы оно совпадало с обеими сторонами.

Ваш классический импорт DLL определяет соглашение с [DllImport(..., CallingConvention=CallingConvention.Cdecl)Вариант, основанный на GetDelegateForFunctionPointer не определяет соглашение о вызовах (и, следовательно, использует StdCall). Вы должны указать это с [UnmanagedFunctionPointer(CallingConvention.Cdecl)],

Ваш код такой же неправильный без отладчика, он просто скрывает ошибку. Обычно такое несоответствие нарушает балансировку указателя стека, приводя к мгновенному сбою, но код маршаллинга .net, кажется, имеет специальную обработку для указателя стека, избегая этого сбоя. Без отладчика молча глотает ошибку, с помощью отладчика она ее отображает.

4

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]