簡體   English   中英

編組 C++ void* 參數

[英]Marshaling C++ void* parameters

我正在嘗試編組 Adobe XMPToolKitSDK XMPFiles.dll 和 XMPCore.dll。 這是我第一次做這樣的事情,對於不包含“void *”類型參數的方法來說,事情似乎運行良好。 請幫助我使用下面的代碼。 謝謝!

C++ function 是:

void
WXMPMeta_GetProperty_1 ( XMPMetaRef       xmpObjRef,
                         XMP_StringPtr    schemaNS,
                         XMP_StringPtr    propName,
                         void *           propValue,
                         XMP_OptionBits * options,
                         SetClientStringProc SetClientString,
                         WXMP_Result *    wResult ) /* const */
{
    XMP_ENTER_ObjRead ( XMPMeta, "WXMPMeta_GetProperty_1" )
    
        if ( (schemaNS == 0) || (*schemaNS == 0) ) XMP_Throw ( "Empty schema namespace URI", kXMPErr_BadSchema );
        if ( (propName == 0) || (*propName == 0) ) XMP_Throw ( "Empty property name", kXMPErr_BadXPath );
        
        XMP_StringPtr valuePtr = 0;
        XMP_StringLen valueSize = 0;

        XMP_OptionBits voidOptionBits = 0;
        if ( options == 0 ) options = &voidOptionBits;

        bool found = thiz.GetProperty ( schemaNS, propName, &valuePtr, &valueSize, options );
        wResult->int32Result = found;
        
        if ( found && (propValue != 0) ) (*SetClientString) ( propValue, valuePtr, valueSize );

    XMP_EXIT
}

我創建了一個 Wrapper 方法和一個 Delegate,如下所示:

        //typedef void (* SetClientStringProc) (void* clientPtr, XMP_StringPtr valuePtr, UInt32 XMP_StringLen);
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        public delegate void SetClientStringProcDelegate(ref IntPtr clientPtr, string valuePtr, ulong valueLen);

        // 20   1F 00002E30 WXMPMeta_GetProperty_1 = WXMPMeta_GetProperty_1
        [DllImport(".\\XMPToolKitSDK\\XMPCore.dll")]
        public static extern void WXMPMeta_GetProperty_1(
            IntPtr xmpObjRef,
            string schemaNS,
            string propName,
            ref IntPtr propValue,
            ref ulong options,
            SetClientStringProcDelegate SetClientString,
            ref WXMP_Result wResult
            ); /* const */

而且,為了讓我的生活更輕松,我還創建了一個 static class 包含以下方法:

        public static WXMP_Result getProperty(IntPtr xmpObjRef, string schemaNS, string propName, ref IntPtr propValue, ref ulong options, SetClientStringProcDelegate SetClientString)
        {
            WXMP_Result wResult = new WXMP_Result();
            XMPMetaWrapper.WXMPMeta_GetProperty_1(xmpObjRef, schemaNS, propName, ref propValue, ref options, SetClientString, ref wResult);
            return wResult;
        }

在我的測試代碼中,我這樣做:

string schemaNS = kXMP_NS_SKYVIEW;
string propName = "CustomField40";
IntPtr propValue = new IntPtr();
options = 0;
SetClientStringProcDelegate setClientStringDelegate = new SetClientStringProcDelegate(mySetClientString);
WXMP_Result getPropertyResult = XMPMeta.getProperty(xmpMetaObjRef, schemaNS, propName, ref propValue, ref options, setClientStringDelegate);
Console.WriteLine("getPropertyResult: " + propValue);

// Callback Methods
public static void mySetClientString(ref IntPtr clientPtr, string valuePtr, ulong valueLen)
{
   Console.WriteLine("mySetClientString|clientPtr: " + clientPtr + "|valuePtr: " + valuePtr + "|valueLen: " + valueLen);
}

當我運行我的 testCode 時,會調用 Callback function,結果是:

XMP Obtido com sucesso: 472446411633

doesPropertyExistResult: 1

mySetClientString|clientPtr: 0|valuePtr: Objects detected | 4 Faces detected and 2 Faces identified|valueLen: 58

getPropertyResult: 0

如您所見,屬性值是由回調 function“mySetClientString”檢索和打印的,作為 valuePtr。 但是,由於某種原因,我無法弄清楚,通過引用“propValue”傳遞的變量沒有返回任何內容。 我是否正確地將“void *”編組為 IntPtr?

請指教! 提前致謝!

感謝大家的評論,特別是@IS4 指出我所缺少的。 原來的 C++ function 接收到一個 ref void (void*) ,然后通過 ref 傳遞給回調 function,它應該設置在這個參數中返回的最終值。

有一個棘手的問題是獲取原始 function 返回的字符串並將其作為 IntPtr 返回。 我不明白為什么 Adobe 會這樣做,但解決方案是將字符串編組到回調 function 內的 IntPtr 中,然后在 function 運行后將其編組回來。 我已經使用此代碼編輯了原始問題,以便任何尋找此代碼的人都能獲得最終解決方案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM