問題是這樣的;
在cb4中New/ActiveX/ActiveX Libray
然後加入New/ActiveX/Automation Object新增一function為test
IDL描述如下:
[id(0x00000001)]
HRESULT _stdcall test2([out] byte * rhs );test2函數聲明如下:
STDMETHODIMP Triven_Test1Impl::test2(signed_char* rhs)
{
@@ //rhs = new signed_char[12];
memset(rhs,' ',12);
memcpy(rhs,"我想你!",12);
return S_OK;
}
然後build注冊!測試程序如下:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
AnsiString strProgID = GetParam();
Variant Comp1,InterFunc; signed_char* szOut = new signed_char[12];
memset(szOut,' ',12); char* szText = new char[120];
memset(szText,' ',120);
try
{
CoInitialize(NULL);
Comp1 = CreateOleObject(strProgID);
InterFunc = Comp1.OleFunction("test2",szOut);
if (SUCCEEDED(InterFunc))
{
memcpy(szText,szOut,12);
Edit1->Text = AnsiString(szText);
}
}
catch(...)
{
;
}
CoUninitialize();
}想問為什麼@@ //rhs = new signed_char[12];
這一句要注冊掉,才能返回結果---"我想你!"?是不哪有錯?
請指教,我剛學。有很多地方不是很清楚。
在cb4中New/ActiveX/ActiveX Libray
然後加入New/ActiveX/Automation Object新增一function為test
IDL描述如下:
[id(0x00000001)]
HRESULT _stdcall test2([out] byte * rhs );test2函數聲明如下:
STDMETHODIMP Triven_Test1Impl::test2(signed_char* rhs)
{
@@ //rhs = new signed_char[12];
memset(rhs,' ',12);
memcpy(rhs,"我想你!",12);
return S_OK;
}
然後build注冊!測試程序如下:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
AnsiString strProgID = GetParam();
Variant Comp1,InterFunc; signed_char* szOut = new signed_char[12];
memset(szOut,' ',12); char* szText = new char[120];
memset(szText,' ',120);
try
{
CoInitialize(NULL);
Comp1 = CreateOleObject(strProgID);
InterFunc = Comp1.OleFunction("test2",szOut);
if (SUCCEEDED(InterFunc))
{
memcpy(szText,szOut,12);
Edit1->Text = AnsiString(szText);
}
}
catch(...)
{
;
}
CoUninitialize();
}想問為什麼@@ //rhs = new signed_char[12];
這一句要注冊掉,才能返回結果---"我想你!"?是不哪有錯?
請指教,我剛學。有很多地方不是很清楚。
STDMETHODIMP Triven_Test1Impl::test2(BSTR* rhs)
{
*rhs = SysAllocString(L"我想你!");
return S_OK;
}
STDMETHODIMP Triven_Test1Impl::test2(BSTR* rhs)
{
*rhs = SysAllocString(L"我想你!");
return S_OK;
}客戶端調用時,
BSTR szOut= NULL;
.....
SysFreeString(szOut);能釋發掉內存嗎?看了一下Com的資料,建議這樣做
STDMETHODIMP Triven_Test1Impl::test2(BSTR* rhs)
{
const wchar_t wsz[] = L"我想你!" ;
const int iLength = (wcslen(wsz)+1)*sizeof(wchar_t) ;
wchar_t* pBuf = static_cast<wchar_t*>(::CoTaskMemAlloc(iLength)) ;
if (pBuf == NULL)
{
return E_OUTOFMEMORY;
}
wcscpy(pBuf, wsz) ;
*rhs = pBuf ;
return S_OK;
}客戶端調用
BSTR szOut= NULL;
.....
::CoTaskMemFree(szOut);釋放
想請問一下,返回類型為Variant*
怎麼判斷傳過來的類型?
STDMETHODIMP Triven_Test1Impl::test2(TVariant* rhs)
{}
如果用Variant *返回字串是不是不好?
{
*rhs = SysAllocString(L"我來了,你可以走了!");
return S_OK;
}在CB中調用
為什麼這樣調才不報錯
TVariant szOut=NULL;
hResult = Comp1.OleFunction("test2",&szOut);
才不報錯,並能返回結果
BSTR szOut=NULL;
hResult = Comp1.OleFunction("test2",&szOut);
這樣不能返回結果?還有如是這樣調
TVariant szOut=NULL;
hResult = Comp1.OleFunction("test2",&szOut);要不要在客戶端釋放內存?是用VarClear(szOut);來釋放內存?
還是szOut轉換後調用SysFreeString來釋放?請指教,這是我的疑惑處?
typedef signed_char* pchar;
STDMETHODIMP Triven_Test1Impl::test2(pchar rhs)
{
rhs = ...
....
}
这样看,假设pchar为int或者其它基本类型,试想,函数里面改变rhs的值会影响外部吗?
STDMETHODIMP Triven_Test1Impl::test2(signed_char** rhs)
{
*rhs = new signed_char[12];
memset(*rhs,' ',12);
memcpy(*rhs,"我想你!",12);
return S_OK;
}1 字符串传递最好用BSTR
2 其它类型的数据最好用CoTaskMemAlloc()来申请,用CoTaskMenFree()来释放!不然的话,
同语言使用可能没有问题,不同语言就可能会有问题了。
3 传出参数如果用指针传出,请用返回指针的指针(即**),如果传入则不必!
welcome to my web site!
http://www.dpspace.com
{
*rhs = new signed_char[12];
memset(*rhs,' ',12);
memcpy(*rhs,"我想你!",12);
return S_OK;
}
这是不行的,因为无论如何不能正确产生调度代码(你的调用者无法知道你用的是HeapAlloc,LoacalAlloc, GlobalAlloc,MapViewOfFile,甚至是别的指针),所以最终的组件是不健全的。
但是你可以改由客户端分配内存,这也是C++编程最为广泛的方式,然后midl可以用
[out, size_is(...), length_is(...)] char* buff, size_is, length_is的详细解释你可以参考msdn。