Passing strings from VC to a VB COM dll
-
My VB function signature is:
Public Function MakeDB(txtFilename As String, dataBaseName As String)
I will pass these two parameters from VC as:
CString dbName, myFile;
edit1.GetWindowText(dbName); edit2.GetWindowText(myFile); ptr->MakeDB(myFile, dbName)
What I need to know is can I do this or do CStrings and VB strings differ. if so, how to pass these strings to the VB dll? Thanks, ns
Well, I did what I said above, and got the VC compile error:
C:\msway\mswayView.cpp(174) : error C2664: 'MakeDB' : cannot convert parameter 1 from 'class CString' to 'unsigned short ** '
with:
ptr.CreateInstance(\_\_uuidof(Class1)); ptr->MakeDB(strFile,dataBaseName);
on the VC side and
Public Function MakeDB(txtPMAFilename As String, dataBaseName As String)
on the VB side. Help!! Thanks, ns (ps. I am going to convert my CStrings into char * but dont know if that will do it...)
-
Well, I did what I said above, and got the VC compile error:
C:\msway\mswayView.cpp(174) : error C2664: 'MakeDB' : cannot convert parameter 1 from 'class CString' to 'unsigned short ** '
with:
ptr.CreateInstance(\_\_uuidof(Class1)); ptr->MakeDB(strFile,dataBaseName);
on the VC side and
Public Function MakeDB(txtPMAFilename As String, dataBaseName As String)
on the VB side. Help!! Thanks, ns (ps. I am going to convert my CStrings into char * but dont know if that will do it...)
Nope. this time with char* passed into VB, I got the compile error in VC:
C:\Trainer\A_TR NOBlob inDB series\VBDBDll2\msway\mswayView.cpp(185) : error C2664: 'MakeDB' : cannot convert parameter 1 from 'char *' to 'unsigned short ** '
Now what to try? Thanks, ns
-
My VB function signature is:
Public Function MakeDB(txtFilename As String, dataBaseName As String)
I will pass these two parameters from VC as:
CString dbName, myFile;
edit1.GetWindowText(dbName); edit2.GetWindowText(myFile); ptr->MakeDB(myFile, dbName)
What I need to know is can I do this or do CStrings and VB strings differ. if so, how to pass these strings to the VB dll? Thanks, ns
VB uses BSTRs I believe, so use temporary CComBSTR variables in your call:
ptr->MakeDB ( CComBSTR(LPCTSTR(myFile)), CComBSTR(LPCTSTR(dbName)) );
--Mike-- Just released - RightClick-Encrypt v1.4 - Adds fast & easy file encryption to Explorer My really out-of-date homepage Sonork-100.19012 Acid_Helm
-
Nope. this time with char* passed into VB, I got the compile error in VC:
C:\Trainer\A_TR NOBlob inDB series\VBDBDll2\msway\mswayView.cpp(185) : error C2664: 'MakeDB' : cannot convert parameter 1 from 'char *' to 'unsigned short ** '
Now what to try? Thanks, ns
The short answer:place a call to SysAllocString around your char*. The longer one: Strings in COM are not 'char*' , but 'BSTR', which is a length-prefixed, wide-character string. Furthermore, allocation of these BSTR must be handled by the COM runtime, you are not allowed to do it yourself. SysAllocString() allocates a block of memory to hold the string you passed it, converted to a widestring and returns a pointer to this memory-block. You can use that pointer as an argument in your method-call. When your finished with the BSTR, you should call SysFreeString() on it. If you're going to use COM from C++, you will save yourself a lot of trouble by reading some initiating articles, like Beginner's Tutorial: Calling Visual Basic ActiveX DLLs from Visual C++ here at The Code Project.
-
The short answer:place a call to SysAllocString around your char*. The longer one: Strings in COM are not 'char*' , but 'BSTR', which is a length-prefixed, wide-character string. Furthermore, allocation of these BSTR must be handled by the COM runtime, you are not allowed to do it yourself. SysAllocString() allocates a block of memory to hold the string you passed it, converted to a widestring and returns a pointer to this memory-block. You can use that pointer as an argument in your method-call. When your finished with the BSTR, you should call SysFreeString() on it. If you're going to use COM from C++, you will save yourself a lot of trouble by reading some initiating articles, like Beginner's Tutorial: Calling Visual Basic ActiveX DLLs from Visual C++ here at The Code Project.
:)Thanks. I was following the article from CP and got MIDL compiler errors so gave up. I see that hes just passing a _bstr_t. I'll have to convert the GetWindowText(pathName) to a _bstr_t. You say that allocation has to be done by the COM runtime, yet the article just passes in a _bstr_t. I'm probably missing something here. Thanks very much for the response. I get to try it tomorrow.
-
VB uses BSTRs I believe, so use temporary CComBSTR variables in your call:
ptr->MakeDB ( CComBSTR(LPCTSTR(myFile)), CComBSTR(LPCTSTR(dbName)) );
--Mike-- Just released - RightClick-Encrypt v1.4 - Adds fast & easy file encryption to Explorer My really out-of-date homepage Sonork-100.19012 Acid_Helm
-
:)Thanks. I was following the article from CP and got MIDL compiler errors so gave up. I see that hes just passing a _bstr_t. I'll have to convert the GetWindowText(pathName) to a _bstr_t. You say that allocation has to be done by the COM runtime, yet the article just passes in a _bstr_t. I'm probably missing something here. Thanks very much for the response. I get to try it tomorrow.
-
VB uses BSTRs I believe, so use temporary CComBSTR variables in your call:
ptr->MakeDB ( CComBSTR(LPCTSTR(myFile)), CComBSTR(LPCTSTR(dbName)) );
--Mike-- Just released - RightClick-Encrypt v1.4 - Adds fast & easy file encryption to Explorer My really out-of-date homepage Sonork-100.19012 Acid_Helm
-
The short answer:place a call to SysAllocString around your char*. The longer one: Strings in COM are not 'char*' , but 'BSTR', which is a length-prefixed, wide-character string. Furthermore, allocation of these BSTR must be handled by the COM runtime, you are not allowed to do it yourself. SysAllocString() allocates a block of memory to hold the string you passed it, converted to a widestring and returns a pointer to this memory-block. You can use that pointer as an argument in your method-call. When your finished with the BSTR, you should call SysFreeString() on it. If you're going to use COM from C++, you will save yourself a lot of trouble by reading some initiating articles, like Beginner's Tutorial: Calling Visual Basic ActiveX DLLs from Visual C++ here at The Code Project.
I tried your method and still got the compile error:
C:\msway\mswayView.cpp(169) : error C2664: 'SysAllocString' : cannot convert parameter 1 from 'char *' to 'const unsigned short *'
My VB dll function that I'm passing to has the signature:
Public Function MakeDB(txtPMAFilename As String, dataBaseName As String)
and I just tried:
CString dataBaseName0 = "C:\\\\Image.mdb"; CString strFile0 = "C:\\\\Trainer\\\\final1.txt"; char\* dataBaseName = new char\[dataBaseName0.GetLength() +1\]; strcpy(dataBaseName, dataBaseName0); `_bstr_t b_dataBaseName = SysAllocString (dataBaseName);` char\* strFile = new char\[strFile0.GetLength() +1\]; strcpy(strFile, strFile0); `_bstr_t b_strFile = SysAllocString (strFile);` //short st1; // Declare the Interface Pointer for your Visual Basic object. Here, // \_Class1Ptr is the Smart pointer wrapper class representing the // default interface of the Visual Basic object. \_Class1Ptr ptr; // Create an instance of your Visual Basic object, here // \_\_uuidof(Class1) gets the CLSID of your Visual Basic object. ptr.CreateInstance(\_\_uuidof(Class1)); `ptr->MakeDB( b_strFile, b_dataBaseName);` SysFreeString (b\_dataBaseName); SysFreeString (b\_strFile);
-
I tried your method and still got the compile error:
C:\msway\mswayView.cpp(169) : error C2664: 'SysAllocString' : cannot convert parameter 1 from 'char *' to 'const unsigned short *'
My VB dll function that I'm passing to has the signature:
Public Function MakeDB(txtPMAFilename As String, dataBaseName As String)
and I just tried:
CString dataBaseName0 = "C:\\\\Image.mdb"; CString strFile0 = "C:\\\\Trainer\\\\final1.txt"; char\* dataBaseName = new char\[dataBaseName0.GetLength() +1\]; strcpy(dataBaseName, dataBaseName0); `_bstr_t b_dataBaseName = SysAllocString (dataBaseName);` char\* strFile = new char\[strFile0.GetLength() +1\]; strcpy(strFile, strFile0); `_bstr_t b_strFile = SysAllocString (strFile);` //short st1; // Declare the Interface Pointer for your Visual Basic object. Here, // \_Class1Ptr is the Smart pointer wrapper class representing the // default interface of the Visual Basic object. \_Class1Ptr ptr; // Create an instance of your Visual Basic object, here // \_\_uuidof(Class1) gets the CLSID of your Visual Basic object. ptr.CreateInstance(\_\_uuidof(Class1)); `ptr->MakeDB( b_strFile, b_dataBaseName);` SysFreeString (b\_dataBaseName); SysFreeString (b\_strFile);
This is all you'll be needing: _bstr_t b_dataBaseName = "C:\\Image.mdb"; _bstr_t b_strFile = "C:\\Trainer\\final1.txt"; _Class1Ptr ptr; ptr.CreateInstance(__uuidof(Class1)); ptr->MakeDB( b_strFile, b_dataBaseName); I have given the impression that it was SysAllocString takes a char* and converts it to a widestring. That is not true. Sorry for that. In the above code, the _bstr_t does all the work for you: - it converts the char* to wchar_t* - it makes calls to SysAllocString() and SysFreeString() when needed So there's no need to make calls to SysAllocString yourself when using a _bstr_t.
-
This is all you'll be needing: _bstr_t b_dataBaseName = "C:\\Image.mdb"; _bstr_t b_strFile = "C:\\Trainer\\final1.txt"; _Class1Ptr ptr; ptr.CreateInstance(__uuidof(Class1)); ptr->MakeDB( b_strFile, b_dataBaseName); I have given the impression that it was SysAllocString takes a char* and converts it to a widestring. That is not true. Sorry for that. In the above code, the _bstr_t does all the work for you: - it converts the char* to wchar_t* - it makes calls to SysAllocString() and SysFreeString() when needed So there's no need to make calls to SysAllocString yourself when using a _bstr_t.
Great! Thanks. Now the only remaining thing to iron out in this issue is that the VB dll functions argument had to be changed to
MyFunc(ByVal as String)
or it wouldnt compile. This seems to indicate that I cant pass in a _bstr_t that I want modified by the dll and have the changes persist in the VC - I mean by passing in the _bstr_t by reference. Like if I wanted the VB dll to fill in myBstrString, I'd call it like:ptr->FillString(&myBstrString)
pls correct me here if I am wrong in calling it like this to get what I want
and in the VB dllFunction FillString(ByRef a as String)
a ="filledByVB"
I'd really appreciate if you can let me know if I'm understanding this pass by reference notion correctly (esp on the VC side - maybe I dont need that & in the ptr call, do I? If the argument was an int or something, I know for sure we'd need to pass in &myInt, and the & would be necessary ) Anyways the time the compiler was unhappy was when the dl had ByRef and I sent in the _bstr_t like this:
ptr->FillString( myBstrString);
Thanks, ns