我正在研究一些涉及使用P/Invoke從幾個C++ DLL調用非託管函數的代碼。我希望能夠將應用程序構建爲32位或64位。如何使用P/Invoke從64位C#應用程序調用64位C++ DLL?
目前,它只能用作x86。
我有每個引用的C++ DLL的32位和64位副本,並且使用以下代碼來更改DllDirectory,具體取決於應用程序是構建爲x86還是x64(/ lib/x64保存64位dll ,/ lib中/ 86保持32位的):
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
static extern bool SetDllDirectory(string lpPathName);
string libPath = Path.Combine(Environment.CurrentDirectory, "lib", (Environment.Is64BitProcess == true ? "x64" : "x86"));
SetDllDirectory(libPath);
我的非託管C++函數被定義爲的其餘部分如下:
[DllImport("libgobject-2.0-0.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
static extern void g_type_init();
[DllImport("libgobject-2.0-0.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
static extern void g_object_unref(IntPtr pixbuf);
[DllImport("librsvg-2-2.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
static extern IntPtr rsvg_pixbuf_from_file_at_size(string file_name, int width, int height, out IntPtr error);
[DllImport("libgdk_pixbuf-2.0-0.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
static extern bool gdk_pixbuf_save(IntPtr pixbuf, string filename, string type, out IntPtr error, __arglist);
實際使用這些函數的代碼類似於此:
g_type_init();
IntPtr ptrError;
IntPtr ptrPixbuf = rsvg_pixbuf_from_file_at_size(filePath, width, height, out ptrError);
if (ptrError == IntPtr.Zero)
{
bool isSaved = gdk_pixbuf_save(ptrPixbuf, outputPath, outputFormat, out ptrError, __arglist(null)); //this line fails when compiled as x64!
if (isSaved && File.Exists(outputPath))
{
return outputPath;
}
}
g_object_unref(ptrPixbuf);
正如我所提到的,當我的本地機器上運行應用程序爲x86時,一切正常(Windows 7 x64)。但是,當我將它編譯爲x64應用程序時,我在調用gdk_pixbuf_save()時收到「AccessViolationException」。
任何想法?我對互操作代碼比較陌生,但我認爲它可能與IntPtr變量如何發送到非託管代碼有關。但爲什麼它不同於x86到x64?
你將不得不調試它,所以你至少有一個想法哪個參數是錯誤的。在本機C++代碼上設置一個斷點並從此處取得斷點。 –
__arglist沒有記錄,所以也許它只是不工作...... –
你有沒有嘗試明確定義額外的參數,而不是使用__arglist? – master131