我有(在C#)COM組件C#字符串數組,具有以下接口:通行證結構或從C++使用COM
namespace InterOp
{
[StructLayout(LayoutKind.Sequential)]
public struct MyStruct
{
[MarshalAs(UnmanagedType.BStr)]
public string name;
[MarshalAs(UnmanagedType.BStr)]
public string surname;
public int age;
}
public interface ITest
{
void SetStringArray(string[] array);
void SetStructArray(MyStruct[] array);
}
public class Test : ITest
{
// string arrays
public void SetStringArray(string[] array)
{
for(int i = 0; i < array.Length; i++)
MessageBox.Show(array[i]); // just do something with the array values
}
// struct arrays
public void SetStructArray(MyStruct[] array)
{
for (int i = 0; i < array.Length; i++)
MessageBox.Show(array[i].name + ", " + array[i].surname + " (" + array[i].age.ToString() + ")");// just do something with the array values
}
}
}
現在我想從C++數據傳遞給COM對象。 我初始化這樣的接口:
HRESULT hr = CoInitialize(NULL);
ITest* pTest = NULL;
hr = CoCreateInstance(__uuidof(Test), NULL, CLSCTX_INPROC_SERVER, __uuidof(ITest), (void**)&pTest);
但我不能一提到我的數組傳遞給方法,因爲它需要一個SAFEARRAY *數組。我能夠與固定大小的元素,如雙,INT,字符數組陣列創建SAFEARRAYS,它使用類似這工作得很好:
SAFEARRAY* data = SafeArrayCreate(VT_R8, 1, &bound); //8-Byte-Real, 1 dimension
當然,對於我的用戶自定義的結構沒有「VT_something 「,所以我不知道如何創建SAFEARRAY來解決這個問題。我嘗試過VT_DISPATCH和VT_BSTR,但沒有成功。
傳遞數據的實際方法是這樣的一個:
bool SetStructArrayEx(MyInterOp::MyStruct* array, int arraySize, ITest* comObjectInterface)
{
bool retVal = false;
// Create the safearray environment
SAFEARRAYBOUND bound;
bound.lLbound = 0;
bound.cElements = arraySize;
// Init the safearray
SAFEARRAY* data = SafeArrayCreate(VT_DISPATCH, 1, &bound);
// access the safearray data and copy the original data to it
MyInterOp::MyStruct HUGEP* temp;
HRESULT hr = SafeArrayAccessData(data, (void HUGEP* FAR*)&temp);
if(SUCCEEDED(hr))
{
// finally copy the data
for(int i=0; i<arraySize; ++i)
*temp++ = array[i];
comObjectInterface->SetStructArray(data);
SafeArrayUnaccessData(data);
retVal = true;
}
SafeArrayDestroy(data);
return retVal;
}
...這不工作(主叫SetStructArray
異常時Kernel32.dll中)。
任何想法,我錯了嗎?或者什麼工作?
感謝, 馬庫斯
看起來很有希望。不幸的是,我從一個問題到下一個問題:使用SafeArrayCreateEx()我需要使用GetRecordInfoFromGuids()來獲取IRecordingInfo。爲此,我需要一些我沒有的IDL文件。似乎通常.tlb是從IDL文件創建的,但VS2005 C#編譯器創建了沒有IDL文件的tlb文件...我會繼續嘗試... – 2011-01-06 17:52:02
@Markus您需要什麼IDL - - GUID?啓動OleView(打開Visual Studio命令提示符並鍵入'oleview'),然後將.tlb加載到它。 – 2011-01-06 17:57:33
謝謝 - 我從註冊表中提取了GUID,但使用該工具當然要容易得多。我有問題得到IRecordInfo(實際上它接受我的GUID),但我終於設法解決所有這些 - 它工作正常。您發佈的鏈接非常有幫助! – 2011-01-07 00:23:53