2013-02-25 6 views
2

Qt 프레임 워크 (http://qt.digia.com/)의 개체에 액세스하려면 C# 및 P-Invoke를 사용하고 있습니다. 간단한 형식 (또는 void)을 반환하는 함수를 사용하는 데 문제가있는 것 같지 않지만 개체를 ​​반환하는 함수를 사용하려고 할 때마다 응용 프로그램이 충돌합니다.타사 DLL의 메서드 호출

예를 들어, QtXml4.dll에는 QString 형식의 개체를 반환하는 QXmlInputSource :: data (void) 메서드가 있습니다. 여기

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"; 
    } 

} 

그리고 후크가 유효한 QXmlInputSource 객체를 제공하는 함수 호출로 (EasyHook 사용) 일부 코드는 다음과 같습니다 : 여기 내 래퍼 클래스는

// 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, 반환 유형, 마샬링 등 다양한 조합을 시도했지만 실제 작동하는 것은 찾지 못했습니다.

도움을 주시면 감사하겠습니다.

또한 사이트의 모든 기여자 들께 감사드립니다. 귀중한 자료입니다!

+0

엔트리 포인트를 빼고 라이브러리에 직접 액세스하려 했습니까? –

+0

아니요, EntryPoint 특성이 없기 때문에 정적 extern 선언에 사용할 함수 이름을 모르겠습니다. 이것들은 정적 함수가 아닌 객체의 멤버 함수라는 것을 기억하십시오. 올바른 메소드를 식별하려면 데코 레이팅 된 이름 (예 : "? parse @ QXml ...")이 필요합니다. –

+0

개체 (인스턴스)가없는 경우 메서드를 호출 할 수 없다는 점을 고려 했습니까? –

답변

3

P/invoke를 사용하여 이와 같이 C++ 라이브러리를 호출 할 수는 없습니다. 당신은 단순히 직업에 대한 잘못된 도구를 가졌을뿐입니다.

당신이해야 할 일은 C++/CLI 혼합 모드 레이어를 사용하여 작업을 수행하는 것입니다. 이것은 실제로 일하는 분명한 이점이있을뿐만 아니라 훨씬 쉬울 것입니다. 네이티브 Qt DLL을 호출하는 C++ 코드를 작성하십시오. 그런 다음 해당 코드를 관리되는 클래스를 사용하여 C#에 노출합니다. 마지막으로 C# 코드에서 C++/CLI 라이브러리에 대한 참조를 추가하면됩니다.

+0

항상 희망이 있습니다! : P 나는 당신의 말을 받아 들일 것이다. 나는 다른 질문으로 하루나 이틀에 돌아올 것이라고 확신합니다 ... –

+0

나는 당신의 반응을 실제로 upvote 할 수 없습니다. –

+0

담당자가 더있을 때까지 답변을 수락하면됩니다. 어쨌든, 나는 좋은 질문 인 질문을 upvoting하여 당신에게 몇 가지 담당자를 제공 할 것입니다. 나는 종종 질문을 upvote 잊지. –

관련 문제