我一直在這個圈子上圍繞谷歌,我可以找到各種討論,很多建議,但似乎沒有工作。我有一個ActiveX組件,它將圖像作爲字節數組。當我做TLB導入時,它帶有這個簽名:C#元帥字節[]到COM SAFEARRAY參數與「參考對象」簽名
int HandleImage([MarshalAs(UnmanagedType.Struct)] ref object Bitmap);
如何將字節[]傳遞給那個?
還有另一個函數可以用類似的簽名返回數據,它的工作原理是因爲我可以傳入「null」。返回的類型是一個字節[1..size](非零有界的byte [ ])。但即使我嘗試傳入返回的內容,它仍然會遇到類型不匹配的異常。
更多細節:
我已經編輯在IDispatch接口簽名的方法(使用ILSpy取出從自動生成的互操作組件的界面)。我已經嘗試過下面的每個組合,它總是得到類型不匹配的異常:
- 添加和刪除「裁判」
- 更改參數的數據類型爲「字節[]」或「陣列」
- 編組爲[MarshalAs(UnmanagedType.SafeArray,SafeArraySubType = VarEnum.VT_UI1)]。在與MarshalAs玩了很久之後,我開始相信IDispatch不會使用這些屬性。
還試圖用「Ref對象」接口是,並將其傳遞不同的類型:字節[],Array.CreateInstance(typeof運算(字節)(我認爲都是相同的,但是我發現有人建議它,所以它不能傷害嘗試)
下面是一個創建一個適當的數組中傳遞的Delphi代碼示例:。
var
image: OLEVariant;
buf: Pointer;
image := VarArrayCreate([0, Stream.Size], VarByte);
Buf := VarArrayLock(image);
Stream.ReadBuffer(Buf^, Stream.Size);
VarArrayUnlock(image);
這裏的C代碼做同樣的事情,我想,如果我無法從C#中使用它,我可以通過託管C++調用它,但我寧願將所有內容都放在一個項目中:
long HandleImage(unsigned char* Bitmap, int Length)
{
VARIANT vBitmap;
VariantInit (&vBitmap);
VariantClear(&vBitmap);
SAFEARRAYBOUND bounds[1];
bounds[0].cElements = Length;
bounds[0].lLbound = 1;
SAFEARRAY* arr = SafeArrayCreate(VT_UI1, 1, bounds);
SafeArrayLock(arr);
memcpy(arr->pvData, Bitmap, Length);
SafeArrayUnlock(arr);
vBitmap.parray = arr;
vBitmap.vt = VT_ARRAY | VT_UI1;
long result;
static BYTE parms[] = VTS_PVARIANT;
InvokeHelper(0x5e, DISPATCH_METHOD, VT_I4, (void*)&result, parms,
&vBitmap);
SafeArrayDestroy(arr);
VariantClear(&vBitmap);
return result;
}
你有樣品如何在C#上做到這一點? –
對不起,實際的實現是在我以前的僱主代碼庫中,但我認爲可以口頭描述所有部分如何組合在一起......這足以讓某人獲得足夠的信息來自己實現一點點的工作。 –
多大的一堆臭味。 – Zack