|
Hi !
I'm beginning with COM, and I'd like to do a very simple ATL component with Visual C++.
The interface of this component would implement only one method, which would return a string.
Then, I want to use this component from Visual Basic, and read the string.
The problem I'm having is I don't know how to pass to VB a BSTR. what would be the definition of my Method of the interface ? Can I do this :
HRESULT GetString([out, retval] BSTR str);
In C++, how can I create this BSTR ? Do I have to build the BSTR structure myself from a normal C++ array of chars ?
Thank you for your help,
Jerome
|
|
|
|
|
Jerome C wrote:
what would be the definition of my Method of the interface ?
When you implement method no difference betwenn VB and VC.
Mazy
"So,so you think you can tell,
Heaven from Hell,
Blue skies from pain,...
How I wish,how I wish you were here." Wish You Were Here-Pink Floyd-1975
|
|
|
|
|
Jerome, the GetString should be defined like this :
HRESULT GetString([out, retval] BSTR* str);
In the cpp file:
STDMETHODIMP GetString(BSTR* str)
{
//you must allocate space, vb will call SysFreeString Automatically
*str = SysAllocString("xpto");
return S_OK;
}
If it was a [in] method the str didn't need a pointer.
Cheers,
Joao Vaz
|
|
|
|
|
Thank you both for your help ! It works !!!!
Jerome
|
|
|
|
|
I extracted the system32\vbscript.dll to get the type library(named RegExp.tlb). Then I add the new classes from this tlb to my project! Then I want to new one class of them named IRegExp(derived from COleDispatchDriver), but i don't know whether i need to attach the LPDISPATCH to this instance and how can i do! When i didn't attached it, that is called its default constructor, and run it, I can't not execute it normally! This program is too emengent, so i need ur warmhearted help in time!
[ccode]
void CInetSessionDlg::ParsePage(CString szPattern, CString szContent)
{
//m_regExp's declaration is on other place link this: IRegExp m_regExp;
//The class IMatchCollection and IMatch are both got from the tlb
IMatchCollection * temp;
m_regExp.SetIgnoreCase(TRUE);
m_regExp.SetPattern(szPattern);
if(m_regExp.Test(szContent))
{
temp=new IMatchCollection(m_regExp.Execute(szContent));
for(long i = 0; i < 3/*matches.GetCount()*/; i++)
{
//IMatch match = matches.GetItem(i);
IMatch match = temp->GetItem(i);
CString strLink = match.GetValue();
m_cbHref.AddString(strLink);
}
}
}
[/ccode]
Thanks u very much!
Sincerely, Davidlou
davidlou68@hotmail.com
|
|
|
|
|
Can someone please help me out!!!
I just don't know how to pass/receive binary data between a VB6 client application and an ATL COM Server (EXE).
How can I transform this into COM?
HRESULT MyFunc( unsigned short* pbIn, long cbIn, unsigned short** ppbOut );
Where pbIn is of cbIn-size. The output shall be a size-dynamic buffer holding the result.
Can I use VB6 to call this method using Byte arrays?
Need help
|
|
|
|
|
COM must know at runtime the size of the buffer you want to marshall. So in your case you should declare the method in your IDL file like this :
interface XXX
{
HRESULT MyFunc( [in]long cbIn,[in,size_is(cbIn)] unsigned short *pbIn,[out]long* pbOut,[out,size_is( ,*pbOut)]unsigned short** ppbOut);
};
Or if you want to use the automation marshaller you can pass the array as SAFEARRAY, which is a VARIANT compatible type.
|
|
|
|
|
Hi Stefan, one way that to pass binary data is to use BSTRs, using the api
SysAllocStringByteLen , this creates a string with binary data .
I actually used that doing a atl com object that passed binary data to vb6.
I don't remember well, but since VB6 work with unicode internally , i think that you must allocate 2*nBytes that you want to pass to VB, but I'm not sure if you really need to double the nª of bytes, so you should try the first one.
It's not necessary with BSTR to pass the size, since their size is prefixed at the head of the data, and vb makes use of this.
Hope this helps,
Joao Vaz
|
|
|
|
|
See sample app of COM Variant and Safearrays at
http://www.sellsbrothers.com/tools/CComSafeArray.zip
It also uses VB Clients and C++ COM Object
Best SafeArray Sample that I have seen
(from chris sells site)
|
|
|
|
|
IADsNameTranslate *pNto;
hr = CoCreateInstance
(CLSID_NameTranslate,NULL,CLSCTX_INPROC_SERVER,
IID_IADsNameTranslate,(LPVOID *)&pNto);
if(FAILED(hr))
{
.....
}
CoCreateInstance always fail , HRESULT : 800401f0
any ideas ??
thanx
|
|
|
|
|
You can use Error Lookup Utility ( Comes with Visual Studio) to decode HRESULT. Or add hr,hr in watch window to get full meaning of the hr HRESULT.
HRESULT : 800401f0
means
CoInitialize has not been called.
Deepak Khajuria
|
|
|
|
|
Thanx
|
|
|
|
|
Hi there,
I am trying to switch context within a server. The server is called from an ASP page.
The following code retrieves correctly the client token
but the CreateProcessAsUser fail with error 1314 :
"A required privilege is not held by the client"
the parent account has administrator rights on the local machine. Does he need special privileges like SE_ASSIGNPRIMARYTOKEN_NAME &
SE_INCREASE_QUOTA_NAME ?
the doc say that CreateProcessAsUser enable these privileges automatically. I also uses DCOMCNFG to set impersonation level "delegate", is there a programmatic
way to do this ?
I need help !!
HANDLE hToken,hDup;
CoImpersonateClient();
if ( !OpenThreadToken(
GetCurrentThread(),
TOKEN_ALL_ACCESS ,
FALSE,
&hToken )) {
// openthread error
...
}
CoRevertToSelf();
if ( !DuplicateTokenEx(
hToken,
TOKEN_IMPERSONATE | TOKEN_QUERY |
TOKEN_ASSIGN_PRIMARY | TOKEN_DUPLICATE,
NULL,
SecurityImpersonation,
TokenPrimary,
&hDup
) ) {
// duplicatetoken error
...
}
STARTUPINFO si;
PROCESS_INFORMATION pi;
GetStartupInfo(&si);
if( !CreateProcessAsUser( hDup,
"somecommand",NULL,
NULL,
NULL,
TRUE, NORMAL_PRIORITY_CLASS ,
NULL,
NULL,
&si,
&pi )
)
{
// error
}
|
|
|
|
|
As far as I know the IIS use the IWAM_[machinename] to launch out of process applications, and an anonymous access to IIS will run under IUSR_[machinename] account ( check the users lists from your machine). So if you impersonate your client from your component you will impersonate IWAM_XXX or IUSR_XXX, not the logged on user.
|
|
|
|
|
I checked the client SID before the call to CreateProcessAsUser using
getInfoFromToken( .. ) and then i used
pgetsid.exe (pgetsid DOMAIN\user) to get his SID : they matches. Does this mean
that I am impersonating the right user ? Does the parent executing the server need additional privileges ???
|
|
|
|
|
The security for your virtual directory where the ASP page is located is "integrated windows authentication" without "Allow anonymous access" ? And what about your component : is out of process or in process ?
For CreateProcessAsUser maybe you will find this link helpful : http://www.mvps.org/win32/security/lu_cpau.html
|
|
|
|
|
I have a problem when trying to listen to BREAK signals on serial comm port(UART). I want to start sending data on the comm port after windows have received three BREAK signals.
I am counting the jumps to the BREAK_signal function, I know when to start sending data by simply having a if ( break_detected == 3).
The problem is that when in debug mode, it is working fine, but when in release mode I get an "unhandled exception" message.
Please someone...should I maybe clear some register after one BREAK signal has been set off??? Or where could the solution be found??
|
|
|
|
|
Hi
It is possible to call COM+ application on remonte machine using smart poiners ?
If yes, how to call COM+ application from machine with COM+ application proxy installed ?
Thx 4 Hlp
|
|
|
|
|
In COM you don't care about the object location. When you create an object instance that object can be located anywhere ( in the same process, in another process, or remote ). Smart pointers are just a way to reduce your programming effort when you deal with COM development. So if you want to instantiate a remote component install the proxy on the client machine, create the object and use it.
|
|
|
|
|
hi
I compiled an idl file and a tlb is also made
though the tlb is registered in my system , it is not shown in the OLE COM Object Viewer
what should i do to make the tlb visible in it ?
|
|
|
|
|
Your TypeLib will appear in OLEView only if it is registered ( should be listed in registry under HKCR \ TypeLib). You can see it anyway with OLEView, select File / View TypeLib and browse for your dll, ocx, tlb & the rest.
|
|
|
|
|
hi,
all
I am a newer to learn com progrmming .Now who can tell
me how to generate the guid of interface in com.
Your advanced help will be appreciated.
Best regards.
|
|
|
|
|
GUID guid;
HRESULT hr;
hr = ::CoCreateGuid(&guid);
if(S_OK == hr)
{
//guid is generated
}
soptest
|
|
|
|
|
If you don't need to do it programatically, you can use the guidgen tool to generate one. Just run 'guidgen.exe' (located in your Visual Studio installation's Common\Tools\ folder) and it generates one in a number of formats for cut-and-paster as required.
------------------------
Derek Waters
derek@lj-oz.com
|
|
|
|
|
Hi all,
I have a problem in using tab to shift the focus from one control to another. Mine is an ATL dll with MSF support which has around 20 views in splitter window and each view will be shown when a particular selection is made in the left pane. My problem is that in all these views I am not able to change the focus from one control to another using the tab key though I have set the TabStop property foa al the controls.
Also I tried to handle the Tab key by overriding the PreTranslateMessage function. But the control is not at all going to the function on tab key operation.
Pls give me a soln if any one has.
Thanks in advance,
-manju
|
|
|
|