C#生成com元件形式的dll供C++呼叫
阿新 • • 發佈:2018-12-31
①建立C#類庫(ClassLibrary)、設定AssemblyInfo.cs中的[assembly: ComVisible(true)]預設是false、或者在介面和類之前新增設定為true
[ComVisible(true)]
[Guid("E709D3B9-18E8-4189-B1E0-49F72DD5A74C")]
注:若C#引數需要陣列,則可以定義為Object,C++對應的是VARINT
eg. BOOL CalcuHeightWidth(VARIANT& files, float * fHeight) {
BOOL result;
static BYTE parms[] = VTS_VARIANT VTS_PR4 ;
return result;
}
在COM中傳遞陣列需要SAFEARRY,但是SAFEARRY需要使用VARIANT包裝一下,如下:
VARIANT arryVar;
VariantInit( &arryVar );
arryVar.vt = VT_ARRAY | VT_BSTR;
SAFEARRAY* pSa = SafeArrayCreateVector(VT_BSTR, 0, vecTmpFiles.size());
BSTR* bFile = new BSTR[vecTmpFiles.size()];
for (int i = 0; i < vecTmpFiles.size(); ++i)
{
bFile[i] = SysAllocString(vecTmpFiles.at(i));
SafeArrayPutElement(pSa,(long*)&i, bFile[i]);
}
SafeArrayAccessData(pSa, (void**)&bFile);
arryVar.parray = pSa;
SafeArrayUnaccessData(pSa);
SafeArrayDestroy(pSa); //會自動釋放BSTR* bFile陣列,無需再釋放bFile,否則重複釋放。
[ComVisible(true)]
[Guid("E709D3B9-18E8-4189-B1E0-49F72DD5A74C")]
public interface CombineToolInterface{
[DispId(1)]
bool CalcuHeight(Object files, ref float fHeight)
}
利用VS工具中的建立GUID生成GUID
②定義介面其中每個介面對應一個[DispId(1)] id必須唯一。
③具體實現
[ComVisible(true)]
[Guid("C76A4C63-46DE-4D3A-8DD7-00E71B42D9AA")]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("PDFCombine.CombineToolInterface")]
public class CombineTool : CombineToolInterface{
bool CalcuHeight(Object files, ref float fHeight){
List<string> arrFile = new List<string>((string[])files);
return true;}
}
④預設情況下會生成.tlh和.dll檔案,然後使用VS類嚮導新增類選擇 MFC Class From TypLib..如下圖:
有.h和dll檔案VC就可以使用了。注:若C#引數需要陣列,則可以定義為Object,C++對應的是VARINT
eg. BOOL CalcuHeightWidth(VARIANT& files, float * fHeight) {
BOOL result;
static BYTE parms[] = VTS_VARIANT VTS_PR4 ;
return result;
}
在COM中傳遞陣列需要SAFEARRY,但是SAFEARRY需要使用VARIANT包裝一下,如下:
VARIANT arryVar;
VariantInit( &arryVar );
arryVar.vt = VT_ARRAY | VT_BSTR;
SAFEARRAY* pSa = SafeArrayCreateVector(VT_BSTR, 0, vecTmpFiles.size());
BSTR* bFile = new BSTR[vecTmpFiles.size()];
for (int i = 0; i < vecTmpFiles.size(); ++i)
{
bFile[i] = SysAllocString(vecTmpFiles.at(i));
SafeArrayPutElement(pSa,(long*)&i, bFile[i]);
}
SafeArrayAccessData(pSa, (void**)&bFile);
arryVar.parray = pSa;
SafeArrayUnaccessData(pSa);
SafeArrayDestroy(pSa); //會自動釋放BSTR* bFile陣列,無需再釋放bFile,否則重複釋放。