[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

microsoft.public.dotnet.framework.interop

Unmanaged Code to CCW/C# problem

Glenn

8/18/2007 12:19:00 PM

Hi

I have a C# DLL which has a method which accepts a string argument. This is
registered for COM. The resulting .tlb is then referenced in a native C++
DLL. I then wrap the method in a C++ method and add some trace code. The
wrapped C# method also includes some trace code. When I attempt to run the
C++ method, passing a BSTR to it, the C++ methods trace code fires, however,
the C# method call doesn't appear to do anything.

The strange thing is that if I remove the string argument from the C#
method, regenerate the .tlb and change the wrapper method accordingly the C#
trace code fires. I have other methods which accept and return numeric
types which issue, it's just this one which accepts a BSTR that seems to be
a problem.

I should say that the C++ dll has to be native to integrate with an ancient
PowerBuilder component which can't be changed, hence the C++ to COM to C#
process.

I'm rather lost on this one, as I know almost nothing about C++, so I'd
really appreciate if anyone can give me a few pointers (no pun intended).

Many Thanks

Glenn


5 Answers

Johannes Passing

8/18/2007 1:51:00 PM

0

GlennAnthonyB wrote:
> Hi
>
> I have a C# DLL which has a method which accepts a string argument. This is
> registered for COM. The resulting .tlb is then referenced in a native C++
> DLL. I then wrap the method in a C++ method and add some trace code. The
> wrapped C# method also includes some trace code. When I attempt to run the
> C++ method, passing a BSTR to it, the C++ methods trace code fires, however,
> the C# method call doesn't appear to do anything.
Does anything mean that the call succeeds though the trace code is not
executed or does it hang?

> The strange thing is that if I remove the string argument from the C#
> method, regenerate the .tlb and change the wrapper method accordingly the C#
> trace code fires. I have other methods which accept and return numeric
> types which issue, it's just this one which accepts a BSTR that seems to be
> a problem.
>
> I should say that the C++ dll has to be native to integrate with an ancient
> PowerBuilder component which can't be changed, hence the C++ to COM to C#
> process.
Can you please post the affected code of both the C# and the C++ side?

--Johannes


--
Johannes Passing - http:...

Glenn

8/20/2007 8:15:00 AM

0


"Johannes Passing" <jpassing_at_hotmail_com@nospam.com> wrote in message
news:O4Vzu7Z4HHA.5880@TK2MSFTNGP03.phx.gbl...
> GlennAnthonyB wrote:
>> Hi
>>
>> I have a C# DLL which has a method which accepts a string argument. This
>> is registered for COM. The resulting .tlb is then referenced in a native
>> C++ DLL. I then wrap the method in a C++ method and add some trace code.
>> The wrapped C# method also includes some trace code. When I attempt to
>> run the C++ method, passing a BSTR to it, the C++ methods trace code
>> fires, however, the C# method call doesn't appear to do anything.
> Does anything mean that the call succeeds though the trace code is not
> executed or does it hang?

It's doesn't hang, it just doesn't appear to enter the C# method.

>
>> The strange thing is that if I remove the string argument from the C#
>> method, regenerate the .tlb and change the wrapper method accordingly the
>> C# trace code fires. I have other methods which accept and return
>> numeric types which issue, it's just this one which accepts a BSTR that
>> seems to be a problem.
> >
>> I should say that the C++ dll has to be native to integrate with an
>> ancient PowerBuilder component which can't be changed, hence the C++ to
>> COM to C# process.
> Can you please post the affected code of both the C# and the C++ side?

C# code fragment...

public int Search( string searchString )
{
Trace.TraceInformation( "Managed Search method invoked..." );

int status = -1;

return status;
}

C++ code fragment...

#include "stdafx.h"

#import "Test.tlb" raw_interfaces_only

BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
CoInitialize( NULL );
return TRUE;
}

int Search( BSTR searchString )
{
long lResult = 0;

Test::ISearchEnginePtr searchEngine( __uuidof( Test::SearchEngine ) );

searchEngine->Search( searchString, &lResult );

printf( "result %d", lResult );

return lResult;
}


>
> --Johannes
>
>
> --
> Johannes Passing - http:...

Thanks

Glenn


Glenn

8/20/2007 10:07:00 AM

0


Interesting point is that if I create a BSTR in the C++ method I can pass
that to the COM wrapped C# method and it works. The issue is using the BSTR
argument passed to the C++ method.


"glennanthonyb" <glenn.csharp@yahoo.co.uk> wrote in message
news:eBWg9Iw4HHA.5160@TK2MSFTNGP05.phx.gbl...
>
> "Johannes Passing" <jpassing_at_hotmail_com@nospam.com> wrote in message
> news:O4Vzu7Z4HHA.5880@TK2MSFTNGP03.phx.gbl...
>> GlennAnthonyB wrote:
>>> Hi
>>>
>>> I have a C# DLL which has a method which accepts a string argument.
>>> This is registered for COM. The resulting .tlb is then referenced in a
>>> native C++ DLL. I then wrap the method in a C++ method and add some
>>> trace code. The wrapped C# method also includes some trace code. When I
>>> attempt to run the C++ method, passing a BSTR to it, the C++ methods
>>> trace code fires, however, the C# method call doesn't appear to do
>>> anything.
>> Does anything mean that the call succeeds though the trace code is not
>> executed or does it hang?
>
> It's doesn't hang, it just doesn't appear to enter the C# method.
>
>>
>>> The strange thing is that if I remove the string argument from the C#
>>> method, regenerate the .tlb and change the wrapper method accordingly
>>> the C# trace code fires. I have other methods which accept and return
>>> numeric types which issue, it's just this one which accepts a BSTR that
>>> seems to be a problem.
>> >
>>> I should say that the C++ dll has to be native to integrate with an
>>> ancient PowerBuilder component which can't be changed, hence the C++ to
>>> COM to C# process.
>> Can you please post the affected code of both the C# and the C++ side?
>
> C# code fragment...
>
> public int Search( string searchString )
> {
> Trace.TraceInformation( "Managed Search method invoked..." );
>
> int status = -1;
>
> return status;
> }
>
> C++ code fragment...
>
> #include "stdafx.h"
>
> #import "Test.tlb" raw_interfaces_only
>
> BOOL APIENTRY DllMain( HMODULE hModule,
> DWORD ul_reason_for_call,
> LPVOID lpReserved
> )
> {
> CoInitialize( NULL );
> return TRUE;
> }
>
> int Search( BSTR searchString )
> {
> long lResult = 0;
>
> Test::ISearchEnginePtr searchEngine( __uuidof( Test::SearchEngine ) );
>
> searchEngine->Search( searchString, &lResult );
>
> printf( "result %d", lResult );
>
> return lResult;
> }
>
>
>>
>> --Johannes
>>
>>
>> --
>> Johannes Passing - http:...
>
> Thanks
>
> Glenn
>


Johannes Passing

8/20/2007 3:53:00 PM

0

Hi Glenn,

first, there are some issues with your DllMain. DllMain is not only
called on initialization but also on termination of process/threads, so
you definitely need to switch on ul_reason_for_call rather than always
perform the same action. Furthermore, you should never call CoInitialize
from DllMain - see [1] for details. Depending on the calling
application, this might even be the reason for your problem, so try to
fix this first.

To use COM in a DLL, create a helper thread (in the C++ Search function)
and perform all COM-related work on this thread.

[1] http://download.microsoft.com/downl...
af7777e5-7dcd-4800-8a0a-b18336565f5b/DLL_bestprac.doc

--Johannes

>
>
> "glennanthonyb" <glenn.csharp@yahoo.co.uk> wrote in message
> news:eBWg9Iw4HHA.5160@TK2MSFTNGP05.phx.gbl...
>> "Johannes Passing" <jpassing_at_hotmail_com@nospam.com> wrote in message
>> news:O4Vzu7Z4HHA.5880@TK2MSFTNGP03.phx.gbl...
>>> GlennAnthonyB wrote:
>>>> Hi
>>>>
>>>> I have a C# DLL which has a method which accepts a string argument.
>>>> This is registered for COM. The resulting .tlb is then referenced in a
>>>> native C++ DLL. I then wrap the method in a C++ method and add some
>>>> trace code. The wrapped C# method also includes some trace code. When I
>>>> attempt to run the C++ method, passing a BSTR to it, the C++ methods
>>>> trace code fires, however, the C# method call doesn't appear to do
>>>> anything.
>>> Does anything mean that the call succeeds though the trace code is not
>>> executed or does it hang?
>> It's doesn't hang, it just doesn't appear to enter the C# method.
>>
>>>> The strange thing is that if I remove the string argument from the C#
>>>> method, regenerate the .tlb and change the wrapper method accordingly
>>>> the C# trace code fires. I have other methods which accept and return
>>>> numeric types which issue, it's just this one which accepts a BSTR that
>>>> seems to be a problem.
>>>>
>>>> I should say that the C++ dll has to be native to integrate with an
>>>> ancient PowerBuilder component which can't be changed, hence the C++ to
>>>> COM to C# process.
>>> Can you please post the affected code of both the C# and the C++ side?
>> C# code fragment...
>>
>> public int Search( string searchString )
>> {
>> Trace.TraceInformation( "Managed Search method invoked..." );
>>
>> int status = -1;
>>
>> return status;
>> }
>>
>> C++ code fragment...
>>
>> #include "stdafx.h"
>>
>> #import "Test.tlb" raw_interfaces_only
>>
>> BOOL APIENTRY DllMain( HMODULE hModule,
>> DWORD ul_reason_for_call,
>> LPVOID lpReserved
>> )
>> {
>> CoInitialize( NULL );
>> return TRUE;
>> }
>>
>> int Search( BSTR searchString )
>> {
>> long lResult = 0;
>>
>> Test::ISearchEnginePtr searchEngine( __uuidof( Test::SearchEngine ) );
>>
>> searchEngine->Search( searchString, &lResult );
>>
>> printf( "result %d", lResult );
>>
>> return lResult;
>> }
>>
>>
>>> --Johannes
>>>
>>>
>>> --
>>> Johannes Passing - http:...
>> Thanks
>>
>> Glenn
>>
>
>


--
Johannes Passing - http:...

Glenn

8/21/2007 12:26:00 PM

0

Thanks for the info, appreciate it.

Glenn

"Johannes Passing" <jpassing_at_hotmail_com@nospam.com> wrote in message
news:uv5LuI04HHA.556@TK2MSFTNGP06.phx.gbl...
> Hi Glenn,
>
> first, there are some issues with your DllMain. DllMain is not only called
> on initialization but also on termination of process/threads, so you
> definitely need to switch on ul_reason_for_call rather than always perform
> the same action. Furthermore, you should never call CoInitialize from
> DllMain - see [1] for details. Depending on the calling application, this
> might even be the reason for your problem, so try to fix this first.
>
> To use COM in a DLL, create a helper thread (in the C++ Search function)
> and perform all COM-related work on this thread.
>
> [1] http://download.microsoft.com/downl...
> af7777e5-7dcd-4800-8a0a-b18336565f5b/DLL_bestprac.doc
>
> --Johannes
>
>>
>>
>> "glennanthonyb" <glenn.csharp@yahoo.co.uk> wrote in message
>> news:eBWg9Iw4HHA.5160@TK2MSFTNGP05.phx.gbl...
>>> "Johannes Passing" <jpassing_at_hotmail_com@nospam.com> wrote in message
>>> news:O4Vzu7Z4HHA.5880@TK2MSFTNGP03.phx.gbl...
>>>> GlennAnthonyB wrote:
>>>>> Hi
>>>>>
>>>>> I have a C# DLL which has a method which accepts a string argument.
>>>>> This is registered for COM. The resulting .tlb is then referenced in
>>>>> a native C++ DLL. I then wrap the method in a C++ method and add some
>>>>> trace code. The wrapped C# method also includes some trace code. When
>>>>> I attempt to run the C++ method, passing a BSTR to it, the C++ methods
>>>>> trace code fires, however, the C# method call doesn't appear to do
>>>>> anything.
>>>> Does anything mean that the call succeeds though the trace code is not
>>>> executed or does it hang?
>>> It's doesn't hang, it just doesn't appear to enter the C# method.
>>>
>>>>> The strange thing is that if I remove the string argument from the C#
>>>>> method, regenerate the .tlb and change the wrapper method accordingly
>>>>> the C# trace code fires. I have other methods which accept and return
>>>>> numeric types which issue, it's just this one which accepts a BSTR
>>>>> that seems to be a problem.
>>>>>
>>>>> I should say that the C++ dll has to be native to integrate with an
>>>>> ancient PowerBuilder component which can't be changed, hence the C++
>>>>> to COM to C# process.
>>>> Can you please post the affected code of both the C# and the C++ side?
>>> C# code fragment...
>>>
>>> public int Search( string searchString )
>>> {
>>> Trace.TraceInformation( "Managed Search method invoked..." );
>>>
>>> int status = -1;
>>>
>>> return status;
>>> }
>>>
>>> C++ code fragment...
>>>
>>> #include "stdafx.h"
>>>
>>> #import "Test.tlb" raw_interfaces_only
>>>
>>> BOOL APIENTRY DllMain( HMODULE hModule,
>>> DWORD ul_reason_for_call,
>>> LPVOID lpReserved
>>> )
>>> {
>>> CoInitialize( NULL );
>>> return TRUE;
>>> }
>>>
>>> int Search( BSTR searchString )
>>> {
>>> long lResult = 0;
>>>
>>> Test::ISearchEnginePtr searchEngine( __uuidof( Test::SearchEngine ) );
>>>
>>> searchEngine->Search( searchString, &lResult );
>>>
>>> printf( "result %d", lResult );
>>>
>>> return lResult;
>>> }
>>>
>>>
>>>> --Johannes
>>>>
>>>>
>>>> --
>>>> Johannes Passing - http:...
>>> Thanks
>>>
>>> Glenn
>>>
>>
>>
>
>
> --
> Johannes Passing - http:...