I'm trying to learn how to use managed/unmanaged code interop, but I've hit a wall that 4 hours of googling wasn't able to get over. I put together 2 projects in visual studio, one creating a win32 exe, and one creating a windows forms .NET application. After a bunch of mucking around I got the C# code to call into the c++ code correctly, but from here I started getting AccessViolationException everytime I got in there. Here is the code from the .cpp file:
我正在尝试学习如何使用托管/非托管代码互操作,但我已经碰到了4小时的谷歌搜索无法克服的问题。我在visual studio中组合了2个项目,一个创建了一个win32 exe,另一个创建了一个windows形式的.NET应用程序。经过一堆麻烦后,我得到了C#代码来正确调用c ++代码,但是从这里开始我每次进入时都会遇到AccessViolationException。这是.cpp文件中的代码:
extern "C" __declspec(dllexport) void QuickTest()
{
int iTest = 0;
int aTestArray[3] = {1,2,3};
return;
}
And here is the code from the C# windows forms app calling it:
这里是C#windows窗体应用程序调用它的代码:
[DllImport("UnmanagedEvaluation2.exe")]
static extern void QuickTest();
Pretty simple right? The call works, and I am able to step into the c++ code (I turned on unmanaged debugging for the project), but it dies on the array creating line every single time with AccessViolationException. The same code runs fine when I run the executable (the c++ code is in a console application project, I tried calling it from the _tmain function and no problems), but when calling into it from .NET it blows up every time.
很简单吧?调用工作正常,我可以进入c ++代码(我打开了项目的非托管调试),但它每次使用AccessViolationException都会在数组创建行上死掉。当我运行可执行文件时,相同的代码运行正常(c ++代码在控制台应用程序项目中,我尝试从_tmain函数调用它并没有问题),但是当从.NET调用它时它每次都会爆炸。
There has to be something obvious I am missing here, but I haven't come up with anything useful from reading tutorials, and most of the issues posts about that exception are people having problems with complicated marshalings or GCHandles. Thanks in advance for any help.
我必须在这里找到一些显而易见的东西,但是我没有从阅读教程中得到任何有用的东西,关于该异常的大多数问题都是人们遇到复杂的marshalings或GCHandles的问题。在此先感谢您的帮助。
Update: You were right below, but it's weird. At first when I started this I assumed I wouldn't be able to do that (call into functions in executables), but when I tried it -- it actually did work, the call that is. It seems like it lets you call into a function into an executable, but as soon as you try to allocate any memory it dies. Any way, thanks for the advice, it seems to be working correctly now.
更新:你就在下面,但这很奇怪。起初,当我开始这个时,我假设我无法做到这一点(调用可执行文件中的函数),但是当我尝试它时 - 它实际上确实有效,即调用。看起来它可以让你将函数调用到一个可执行文件中,但是一旦你尝试分配任何内存它就会死掉。无论如何,感谢您的建议,它现在似乎正常工作。
2 个解决方案
#1
You can't call functions in executables from outside those executables. You need to compile your code into a DLL.
您无法从这些可执行文件外部调用可执行文件中的函数。您需要将代码编译为DLL。
#2
You have declared your function as extern "C"
which means it uses cdecl
as its calling convention. By default, DllImport
uses StdCall
as the calling convention. This may be the reason of your code crashing.
您已将函数声明为extern“C”,这意味着它使用cdecl作为其调用约定。默认情况下,DllImport使用StdCall作为调用约定。这可能是您的代码崩溃的原因。
Try importing your function into .NET code as
尝试将您的函数导入.NET代码中
[DllImport("UnmanagedEvaluation2.exe", CallingConvention=CallingConvention.Cdecl)]
static extern void QuickTest();
See http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.callingconvention.aspx for more info.
有关详细信息,请参阅http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.callingconvention.aspx。
#1
You can't call functions in executables from outside those executables. You need to compile your code into a DLL.
您无法从这些可执行文件外部调用可执行文件中的函数。您需要将代码编译为DLL。
#2
You have declared your function as extern "C"
which means it uses cdecl
as its calling convention. By default, DllImport
uses StdCall
as the calling convention. This may be the reason of your code crashing.
您已将函数声明为extern“C”,这意味着它使用cdecl作为其调用约定。默认情况下,DllImport使用StdCall作为调用约定。这可能是您的代码崩溃的原因。
Try importing your function into .NET code as
尝试将您的函数导入.NET代码中
[DllImport("UnmanagedEvaluation2.exe", CallingConvention=CallingConvention.Cdecl)]
static extern void QuickTest();
See http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.callingconvention.aspx for more info.
有关详细信息,请参阅http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.callingconvention.aspx。