对于我已经使用了很长一段时间的一些东西,我得到了这个奇怪的错误.它可能是Visual Studio 2010中的新东西,但我不确定.
我试图用C#调用用C++编写的无人函数.
从我在互联网上阅读的内容和错误信息本身来看,这与我的C#文件中的签名与C++中的签名不同但我真的看不到它这一事实有关.
首先,这是我在下面的无人函数:
TEngine GCreateEngine(int width,int height,int depth,int deviceType);
Run Code Online (Sandbox Code Playgroud)
这是我在C#中的功能:
[DllImport("Engine.dll", EntryPoint = "GCreateEngine", CallingConvention = CallingConvention.StdCall)]
public static extern IntPtr CreateEngine(int width,int height,int depth,int device);
Run Code Online (Sandbox Code Playgroud)
当我调试到C++时,我看到所有的参数都很好,因此我只能认为它与从TEngine(这是一个名为CEngine的类的指针)转换为IntPtr有关.我之前在VS2008中使用过这个没问题.
我测试了很多.但我发现那些2没有缺点!
但是看到接受的答案.
GetLastError托管代码是不安全的,因为框架可能在内部"覆盖"最后一个错误.我从来没有遇到任何明显的问题,GetLastError对我来说,.NET Framework足够智能,不会覆盖它.因此,我对该主题有几个问题:
[DllImport("kernel32.dll", SetLastError = true)]该SetLastError属性是否使Framework存储错误代码供使用Marshal.GetLastWin32Error()?GetLastError无法给出正确的结果?Marshal.GetLastWin32Error()吗?public class ForceFailure
{
[DllImport("kernel32.dll")]
static extern uint GetLastError();
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool SetVolumeLabel(string lpRootPathName, string lpVolumeName);
public static void Main()
{
if (SetVolumeLabel("XYZ:\\", "My Imaginary Drive "))
System.Console.WriteLine("It worked???");
else
{
// the first last error check is fine here:
System.Console.WriteLine(GetLastError());
System.Console.WriteLine(Marshal.GetLastWin32Error());
}
}
}
Run Code Online (Sandbox Code Playgroud)
一种解决方案(the.sln)
一个C++项目(2010年的mycppproject.vcxproj或2008年的mycppproject.vcproj)编译导出某些函数的本机DLL.在调试中,这构建了c:\ output\Debug\mycppproject_d.dll,在发行版中,这构建了c:\ output\Release\mycppproject.dll.
一个包含PInvoke的C#控制台应用程序(mycsharpconsole.csproj)调用DLL.
所有编译都很好.
当我构建时,我希望能够将csharp项目中的引用添加到cpp DLL项目中,以便它可以将相应目录中的相应文件复制到内置csharp项目的\ bin\Debug目录中.
这应该是可能的,因为IDE知道有关构建DLL的位置以及构建C#应用程序的位置的所有内容.
在Visual Studio 2010中:
我在csharp项目上尝试了"Dependencies ..."并添加了对mycppproject的依赖,但这没有任何效果.
我在csharp项目上尝试了"Add Reference ..."并添加了对cpp项目的引用,但是我收到一条警告消息'项目的Target Framework版本"mycppproject"高于当前项目Target Framework版本.您是否要将此引用添加到项目中?(是/否/取消).
单击"是"将生成错误消息"无法添加对mycppproject的引用".
我偶然发现了一个为Microsoft自己的非托管DLL生成P/Invoke签名的工具:PInvoke Interop Assistant
是否有类似的工具将为第三方非托管DLL生成P/Invoke签名?
或者,任何方式将第三方DLL提供给PInvoke Interop Assistant
编辑:我试图解决的实际问题
我有什么可以做的AccessViolationException吗?它是由我无法控制的非托管DLL引发的.
我通过开发人员论坛了解托管非托管应用内产品之间的区别.他们说"未管理的商品没有将他们的交易信息存储在Android Market上,这意味着您无法查询Android Market以检索购买类型被列为非托管的商品的交易信息.您有责任管理交易信息.非托管物品." 这是什么意思?当我测试托管和非托管的应用内商品时,我从服务器获得了正确的响应,在我的商家帐户中,托管和非托管应用的订单也变得明显.请帮我了解这两者之间的区别.
我们的项目结构如,
native.dll: - 这包含用c\c ++编写的纯本机代码.这个native.dll使用*def文件公开了一些函数.
Wrapper Library(wrapper.dll compiled with .Net framework v4.0)-为了使用的功能native.dll,一个Wrapper lib(wrapper.dll)
是写在C++\CLI使用:clr\oldsyntax.此包装具有的所有代码Interoperability和Marshalling.
Application(Console App v4.0)直接用于wrapper.dll使用提供的功能native.dll.
现在这个项目需要在.Net Core中运行.这意味着我们将有一个
.Net Core application会reference wrapper.dll,反过来会参考
native.dll.
我知道这不会直接起作用.但问题是.Net Core(CoreCLR)是否支持 C++\CLI(clr\oldsyntax)运行时环境 ?
如果不是,该应用程序可能的解决方案是什么?
究竟是什么un-managed和managed memory?任何人都能简单解释一下吗?
此外,当托管内存概念被用于RAM,调用托管RAM时,究竟意味着什么.有关"托管RAM"和"非托管RAM"的具体细节是什么?
除了代码本身可以直接访问内存的事实.使用"/ unsafe"编译器标志和"fixed"关键字的其他含义是什么?是否存在与我的.exe的代码签名和部署相关的影响(我的应用程序仅限桌面)?
(这不是关于我是否应该这样做,为什么我的问题在这里讨论)
在我的下一个项目中,我想为C++中已有的代码实现GUI.我的计划是将C++部分包装在DLL中并在C#中实现GUI.我的问题是我不知道如何实现从非托管DLL到manged C#代码的回调.我已经在C#中做了一些开发,但是托管和非托管代码之间的接口对我来说是新的.任何人都可以给我一些提示或阅读提示或一个简单的例子来开始吗?不幸的是,我找不到任何有用的东西.