我正在使用C#和P-Invoke訪問Qt框架(http://qt.digia.com/)中的對象。我似乎沒有遇到使用函數返回簡單類型(或無效)的麻煩,但每當我嘗試使用返回對象的函數時,應用程序都會崩潰。在第三方DLL中調用方法
例如,在QtXml4.dll中,有一個方法QXmlInputSource :: data(void),它返回一個QString類型的對象。這裏是我的包裝類:
public class QXmlInputSource
{
// PInvoke - class QString QXmlInputSource::data(void)
[DllImport("QtXml4.dll", CharSet = CharSet.Unicode, EntryPoint = "[email protected]@@[email protected]@XZ",
SetLastError = true, CallingConvention = CallingConvention.ThisCall)]
static extern IntPtr data(ref IntPtr Ptr);
private IntPtr mPtr;
public QXmlInputSource(IntPtr Ptr)
{
mPtr = Ptr;
}
public override string ToString()
{
IntPtr mData = data(ref mPtr);
return "Epic Fail";
}
}
在這裏的是,掛鉤(使用EasyHook)到一個函數調用,提供了一個有效的QXmlInputSource對象的一些代碼:
// just use a P-Invoke implementation to get native API access from C# (this step is not necessary for C++.NET)
[DllImport("QtXml4.dll", CharSet = CharSet.Unicode, EntryPoint = "[email protected]@@[email protected]@@Z",
SetLastError = true, CallingConvention = CallingConvention.ThisCall)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool XmlParse(IntPtr Reader, IntPtr Source);
// Intercept all calls to parse XML
public bool XmlParse_Intercepted(IntPtr Reader, IntPtr Source)
{
QXmlInputSource XmlSource = new QXmlInputSource(Source);
String s = XmlSource.ToString();
// call original API...
return XmlParse(Reader, Source);
}
的掛鉤代碼似乎很好地工作。當我在包裝類中調用data()函數時,Qt應用程序崩潰。正如我上面所說的,當函數調用返回一個對象而不是簡單類型時,基於Qt的應用程序就會崩潰。
我試過callingconventions,返回類型,封送等各種組合,但沒有偶然發現任何實際工作。
任何幫助非常感謝。
此外,一般感謝您對網站上的所有貢獻者 - 這是一個無價的資源!
您是否嘗試省略入口點並試圖直接訪問庫? – 2013-02-25 08:53:53
不,因爲沒有EntryPoint屬性,我不知道什麼函數名稱用於靜態extern聲明。記住這些是對象的成員函數,而不是靜態函數。裝飾名稱(例如「?parse @ QXml ...」)是識別正確方法所必需的。 – 2013-02-25 09:05:17
那麼,你有沒有考慮過,如果你沒有一個對象(一個實例),你不能調用方法? – 2013-02-25 09:11:50