2012-12-24 85 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放到同一個輸出目錄中。請注意,輸出目錄是特定於每個構建/體系結構組合的。