dotnet interop:
Hi. I suppose I'm not the first to ask this, especially given that I searched and found a few similar things posted here. None of them, however, answered my question. My question is this: I'm trying to pass a normal std::string from VC++ 6.0 to a C# DLL. My .cpp file for my VC++ console application looks like this: #include "stdafx.h" #import "ProblemTranslator.tlb" raw_interfaces_only using namespace ProblemTranslator; int main( int argc, char* argv[] ) { // Initialize COM. HRESULT hr = CoInitialize(NULL); // Create the interface pointer. ITranslatorPtr Trans( __uuidof( Translator ) ); // Call the Process method. Trans->Process( ( BSTR )argv[ 1 ] ); // Uninitialize COM. CoUninitialize(); return 0; } This was taken almost codatim (verbatim with respect to code) from the MS website. It compiles fine. However, it's hitting an access violation somewhere, and I'm not sure what the problem is. Here's the exact access violation, which probably doesn't help: First-chance exception in TranslatorConsole.exe (MSVCR80.DLL): 0xC0000005: Access Violation. I've debugged it down to the point where it's definitely hitting the violation when I call the Process function. It does not, however, get that access violation when I call the DLL from another C# program. The ..tlb header file said the Process function takes a BSTR, so I tried just casting to it. Is that the problem? If that's not it, the header file declaration for the ITranslator interface looks like: ITranslator : IDispatch { // // Raw methods provided by interface // virtual HRESULT __stdcall Process ( BSTR File ) = 0; }; Can anyone help?
You cannot cast a c string to BSTR. Use CComBSTR (atlbase.h) or _bstr_t (comutil.h) classes instead: Trans->Process(CComBSTR(argv[ 1 ] )); or Trans->Process(_bstr_t(CComBSTR(argv[ 1 ] )); Another nasty (but efficient) way is to use USES_CONVERSION macro together with T2COLE macro (atlconv.h) BTW if you #import without 'raw_interfaces_only' generated code (in .tlh and .tli) will use _bstr_t to manage BSTR strings. And last... check for argc parameter to validate argv array. Regards -- Cholo Lennon Bs.As. ARG [quoted text, click to view] "Kyle Szklenski" <kyle.szklenski@gmail.com> wrote in message news:1169744958.420879.140580@k78g2000cwa.googlegroups.com... > Hi. I suppose I'm not the first to ask this, especially given that I > searched and found a few similar things posted here. None of them, > however, answered my question. > > My question is this: I'm trying to pass a normal std::string from VC++ > 6.0 to a C# DLL. My .cpp file for my VC++ console application looks > like this: > > #include "stdafx.h" > #import "ProblemTranslator.tlb" raw_interfaces_only > > using namespace ProblemTranslator; > int main( int argc, char* argv[] ) > { > // Initialize COM. > HRESULT hr = CoInitialize(NULL); > > // Create the interface pointer. > ITranslatorPtr Trans( __uuidof( Translator ) ); > > // Call the Process method. > Trans->Process( ( BSTR )argv[ 1 ] ); > > // Uninitialize COM. > CoUninitialize(); > return 0; > } > > This was taken almost codatim (verbatim with respect to code) from the > MS website. It compiles fine. However, it's hitting an access violation > somewhere, and I'm not sure what the problem is. Here's the exact > access violation, which probably doesn't help: > > First-chance exception in TranslatorConsole.exe (MSVCR80.DLL): > 0xC0000005: Access Violation. > > I've debugged it down to the point where it's definitely hitting the > violation when I call the Process function. It does not, however, get > that access violation when I call the DLL from another C# program. The > .tlb header file said the Process function takes a BSTR, so I tried > just casting to it. Is that the problem? If that's not it, the header > file declaration for the ITranslator interface looks like: > > ITranslator : IDispatch > { > // > // Raw methods provided by interface > // > > virtual HRESULT __stdcall Process ( > BSTR File ) = 0; > }; > > Can anyone help? >
Kyle, [quoted text, click to view] >My question is this: I'm trying to pass a normal std::string from VC++ >6.0 to a C# DLL.
I don't see any std::string used in your code. [quoted text, click to view] >The >.tlb header file said the Process function takes a BSTR, so I tried >just casting to it. Is that the problem?
Yes. Try creating a proper BSTR, either with the SysAlloc* oleaut APIs or a wrapper class like _bstr_t. Mattias -- Mattias Sjögren [C# MVP] mattias @ mvps.org http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Hi, I thank you for your responses, both who replied. I'd like to respond to both separately in one post so I take up less space. Firstly, it's true there was no std::string in my C++ code. That's because at the time of posting that, I had switched it over to the BSTR attempt and forgot to go back and change it. :) Responding to the second post will respond to the first here as well. I tried both methods, and both throw a COM exception. In fact, the exception is thrown in the same place for all three ways that I've tried (casting to BSTR, and both of the methods mentioned below in the quoted text). It is thrown here: Interface* operator->() const throw(_com_error) { if (m_pInterface == NULL) { _com_issue_error(E_POINTER); } return m_pInterface; } In COMIP.h. In the debugger, it steps over the m_pInterface == NULL, which means it's not null, but when it hits the return statement, it throws the error. Any clue what this exception could be? Thanks for your responses again. Kyle [quoted text, click to view] On Jan 25, 2:04 pm, "Cholo Lennon" <chololen...@hotmail.com> wrote: > You cannot cast a c string to BSTR. Use CComBSTR (atlbase.h) or _bstr_t (comutil.h) classes instead: > > Trans->Process(CComBSTR(argv[ 1 ] )); > > or > > Trans->Process(_bstr_t(CComBSTR(argv[ 1 ] )); > > Another nasty (but efficient) way is to use USES_CONVERSION macro together with T2COLE macro (atlconv.h) > > BTW if you #import without 'raw_interfaces_only' generated code (in .tlh and .tli) will use _bstr_t to manage BSTR strings. And > last... check for argc parameter to validate argv array. > > Regards > > -- > Cholo Lennon > Bs.As. > ARG > > "Kyle Szklenski" <kyle.szklen...@gmail.com> wrote in messagenews:1169744958.420879.140580@k78g2000cwa.googlegroups.com... > > Hi. I suppose I'm not the first to ask this, especially given that I > > searched and found a few similar things posted here. None of them, > > however, answered my question. > > > My question is this: I'm trying to pass a normal std::string from VC++ > > 6.0 to a C# DLL. My .cpp file for my VC++ console application looks > > like this: > > > #include "stdafx.h" > > #import "ProblemTranslator.tlb" raw_interfaces_only > > > using namespace ProblemTranslator; > > int main( int argc, char* argv[] ) > > { > > // Initialize COM. > > HRESULT hr = CoInitialize(NULL); > > > // Create the interface pointer. > > ITranslatorPtr Trans( __uuidof( Translator ) ); > > > // Call the Process method. > > Trans->Process( ( BSTR )argv[ 1 ] ); > > > // Uninitialize COM. > > CoUninitialize(); > > return 0; > > } > > > This was taken almost codatim (verbatim with respect to code) from the > > MS website. It compiles fine. However, it's hitting an access violation > > somewhere, and I'm not sure what the problem is. Here's the exact > > access violation, which probably doesn't help: > > > First-chance exception in TranslatorConsole.exe (MSVCR80.DLL): > > 0xC0000005: Access Violation. > > > I've debugged it down to the point where it's definitely hitting the > > violation when I call the Process function. It does not, however, get > > that access violation when I call the DLL from another C# program. The > > .tlb header file said the Process function takes a BSTR, so I tried > > just casting to it. Is that the problem? If that's not it, the header > > file declaration for the ITranslator interface looks like: > > > ITranslator : IDispatch > > { > > // > > // Raw methods provided by interface > > // > > > virtual HRESULT __stdcall Process ( > > BSTR File ) = 0; > > }; > > > Can anyone help?
Hi, sorry about the second post to this. I just ran it through the debugger gain, and put a break point directly inside the COMIP.h file, and found out that it does actually think that the m_pInterface is null. What's the solution there? Do I have to use regasm.exe for the .tlb file inside the folder where I intend to have the tlb, dll, and exe files? I didn't think I did. Kyle [quoted text, click to view] On Feb 1, 10:40 am, "Kyle Szklenski" <kyle.szklen...@gmail.com> wrote: > Hi, > > I thank you for your responses, both who replied. I'd like to respond > to both separately in one post so I take up less space. > > Firstly, it's true there was no std::string in my C++ code. That's > because at the time of posting that, I had switched it over to the > BSTR attempt and forgot to go back and change it. :) > > Responding to the second post will respond to the first here as well. > I tried both methods, and both throw a COM exception. In fact, the > exception is thrown in the same place for all three ways that I've > tried (casting to BSTR, and both of the methods mentioned below in the > quoted text). It is thrown here: > > Interface* operator->() const throw(_com_error) > { > if (m_pInterface == NULL) { > _com_issue_error(E_POINTER); > } > > return m_pInterface; > } > > In COMIP.h. In the debugger, it steps over the m_pInterface == NULL, > which means it's not null, but when it hits the return statement, it > throws the error. Any clue what this exception could be? Thanks for > your responses again. > > Kyle > > On Jan 25, 2:04 pm, "Cholo Lennon" <chololen...@hotmail.com> wrote: > > > You cannot cast a c string to BSTR. Use CComBSTR (atlbase.h) or _bstr_t (comutil.h) classes instead: > > > Trans->Process(CComBSTR(argv[ 1 ] )); > > > or > > > Trans->Process(_bstr_t(CComBSTR(argv[ 1 ] )); > > > Another nasty (but efficient) way is to use USES_CONVERSION macro together with T2COLE macro (atlconv.h) > > > BTW if you #import without 'raw_interfaces_only' generated code (in .tlh and .tli) will use _bstr_t to manage BSTR strings. And > > last... check for argc parameter to validate argv array. > > > Regards > > > -- > > Cholo Lennon > > Bs.As. > > ARG > > > "Kyle Szklenski" <kyle.szklen...@gmail.com> wrote in messagenews:1169744958.420879.140580@k78g2000cwa.googlegroups.com... > > > Hi. I suppose I'm not the first to ask this, especially given that I > > > searched and found a few similar things posted here. None of them, > > > however, answered my question. > > > > My question is this: I'm trying to pass a normal std::string from VC++ > > > 6.0 to a C# DLL. My .cpp file for my VC++ console application looks > > > like this: > > > > #include "stdafx.h" > > > #import "ProblemTranslator.tlb" raw_interfaces_only > > > > using namespace ProblemTranslator; > > > int main( int argc, char* argv[] ) > > > { > > > // Initialize COM. > > > HRESULT hr = CoInitialize(NULL); > > > > // Create the interface pointer. > > > ITranslatorPtr Trans( __uuidof( Translator ) ); > > > > // Call the Process method. > > > Trans->Process( ( BSTR )argv[ 1 ] ); > > > > // Uninitialize COM. > > > CoUninitialize(); > > > return 0; > > > } > > > > This was taken almost codatim (verbatim with respect to code) from the > > > MS website. It compiles fine. However, it's hitting an access violation > > > somewhere, and I'm not sure what the problem is. Here's the exact > > > access violation, which probably doesn't help: > > > > First-chance exception in TranslatorConsole.exe (MSVCR80.DLL): > > > 0xC0000005: Access Violation. > > > > I've debugged it down to the point where it's definitely hitting the > > > violation when I call the Process function. It does not, however, get > > > that access violation when I call the DLL from another C# program. The > > > .tlb header file said the Process function takes a BSTR, so I tried > > > just casting to it. Is that the problem? If that's not it, the header > > > file declaration for the ITranslator interface looks like: > > > > ITranslator : IDispatch > > > { > > > // > > > // Raw methods provided by interface > > > // > > > > virtual HRESULT __stdcall Process ( > > > BSTR File ) = 0; > > > }; > > > > Can anyone help?
One final message: I solved it. I did indeed have to register the COM types in the folder that I'd intended to use them in. Is there a way to make it so that I don't have to register it that way? Perhaps a global registration? It's cool if that won't work. It just means we'll have to put the SDK out on the server so we can register the COM types there too, doesn't it? That's extra work that I'm not happy about having to do, but I will if it'll make this thing work. :) Thanks all. Kyle [quoted text, click to view] On Feb 1, 10:40 am, "Kyle Szklenski" <kyle.szklen...@gmail.com> wrote: > Hi, > > I thank you for your responses, both who replied. I'd like to respond > to both separately in one post so I take up less space. > > Firstly, it's true there was no std::string in my C++ code. That's > because at the time of posting that, I had switched it over to the > BSTR attempt and forgot to go back and change it. :) > > Responding to the second post will respond to the first here as well. > I tried both methods, and both throw a COM exception. In fact, the > exception is thrown in the same place for all three ways that I've > tried (casting to BSTR, and both of the methods mentioned below in the > quoted text). It is thrown here: > > Interface* operator->() const throw(_com_error) > { > if (m_pInterface == NULL) { > _com_issue_error(E_POINTER); > } > > return m_pInterface; > } > > In COMIP.h. In the debugger, it steps over the m_pInterface == NULL, > which means it's not null, but when it hits the return statement, it > throws the error. Any clue what this exception could be? Thanks for > your responses again. > > Kyle > > On Jan 25, 2:04 pm, "Cholo Lennon" <chololen...@hotmail.com> wrote: > > > You cannot cast a c string to BSTR. Use CComBSTR (atlbase.h) or _bstr_t (comutil.h) classes instead: > > > Trans->Process(CComBSTR(argv[ 1 ] )); > > > or > > > Trans->Process(_bstr_t(CComBSTR(argv[ 1 ] )); > > > Another nasty (but efficient) way is to use USES_CONVERSION macro together with T2COLE macro (atlconv.h) > > > BTW if you #import without 'raw_interfaces_only' generated code (in .tlh and .tli) will use _bstr_t to manage BSTR strings. And > > last... check for argc parameter to validate argv array. > > > Regards > > > -- > > Cholo Lennon > > Bs.As. > > ARG > > > "Kyle Szklenski" <kyle.szklen...@gmail.com> wrote in messagenews:1169744958.420879.140580@k78g2000cwa.googlegroups.com... > > > Hi. I suppose I'm not the first to ask this, especially given that I > > > searched and found a few similar things posted here. None of them, > > > however, answered my question. > > > > My question is this: I'm trying to pass a normal std::string from VC++ > > > 6.0 to a C# DLL. My .cpp file for my VC++ console application looks > > > like this: > > > > #include "stdafx.h" > > > #import "ProblemTranslator.tlb" raw_interfaces_only > > > > using namespace ProblemTranslator; > > > int main( int argc, char* argv[] ) > > > { > > > // Initialize COM. > > > HRESULT hr = CoInitialize(NULL); > > > > // Create the interface pointer. > > > ITranslatorPtr Trans( __uuidof( Translator ) ); > > > > // Call the Process method. > > > Trans->Process( ( BSTR )argv[ 1 ] ); > > > > // Uninitialize COM. > > > CoUninitialize(); > > > return 0; > > > } > > > > This was taken almost codatim (verbatim with respect to code) from the > > > MS website. It compiles fine. However, it's hitting an access violation > > > somewhere, and I'm not sure what the problem is. Here's the exact > > > access violation, which probably doesn't help: > > > > First-chance exception in TranslatorConsole.exe (MSVCR80.DLL): > > > 0xC0000005: Access Violation. > > > > I've debugged it down to the point where it's definitely hitting the > > > violation when I call the Process function. It does not, however, get > > > that access violation when I call the DLL from another C# program. The > > > .tlb header file said the Process function takes a BSTR, so I tried > > > just casting to it. Is that the problem? If that's not it, the header > > > file declaration for the ITranslator interface looks like: > > > > ITranslator : IDispatch > > > { > > > // > > > // Raw methods provided by interface > > > // > > > > virtual HRESULT __stdcall Process ( > > > BSTR File ) = 0; > > > }; > > > > Can anyone help?
Don't see what you're looking for? Try a search.
|