2012-12-24 56 views
4

我在C++代码,我由一个DLL导出:内存位置无效的访问 - 托管到非托管代码

typedef struct { 
unsigned short major; 
unsigned short minor; 
} Version; 

EXPORTED_FUNC Result Init(Version *version, char *file); 

extern "C" Result Init(Version *version, char *file) 
{ 
    if (file) { 
    if (!GFile.init(string(file))) { 
     return INVALID_PARAMETER; 
    } 
    if (version) { 
     version->major = VERSION_MAJOR1; 
     version->minor = VERSION_MAJOR2; 
    } 

     return OK; 
} 

我打电话从C#的dll,这是我写的有:

internal struct Version 
{ 
    ushort major { set; get; } 
    ushort minor { set; get; } 
} 

[DllImport("mydll.dll", CallingConvention=CallingConvention.Cdecl)] 
    static extern Result Init(ref Version versionInfo, [MarshalAs`(UnmanagedType.LPStr)] string FilePath); 

,这是呼吁初始化:

string filePath = Application.StartupPath + "\\ABC.ini"; 
Version version = new Version(); 

result = _mydllWrapper.Init(ref version, filePath); 

为所有上面的代码,当我运行的C#应用​​程序,我有时s在x64机器中获得以下例外:

Unable to load DLL mydll.dll : invalid access to memory location (Exception from HRESULT.0x800703E6) 

如何修复此代码而不从编译中删除任何安全标志? 解决方案的代码示例非常好!

谢谢!

+0

尝试删除C#版本中的“{get; set;}”,因为这些子句实际上会将主要/次要转换为特性,而不是字段。此外,我不确定是否可以依靠C++版本和C#版本具有完全相同的内存布局,因为短于机器字。你有没有尝试只初始化Init内的版本,而没有做其他事情(仅用于调试目的)? – chris

回答

0

不幸的是,问题是缺少一些信息,但我只在编译输出错误时才看到错误。它只会偶尔发生,因为你偶尔会删除.Net EXE的输出目录,然后进行构建,然后在问题出现之后,从本地输出目录复制新建的二进制文件,然后继续。

为了解决这个问题,你应该确保你的.NET代码&你的本地代码之间有适当的匹配目标CPU类型。如果你只在x64机器上运行,你可以使用AnyCPU,但我建议,因为你调用的是本地代码,所以你只需要继续&将CPU设置为你的目标,无论是x64,x86(用C++语言描述的Win32)或ARM。另一个与VS2012一起使用的替代方案是“32位首选”目标,它允许您在x64设备上以x86形式运行,但在ARM设备上也可以正常工作。

无论如何,一旦你确保你的配置是正确的,检查以确保你的输出目录设置正确,将.NET EXE和C++ DLL放到同一个输出目录中。请注意,输出目录是特定于每个构建/体系结构组合的。