Hi Peter,
this thread is getting longer than I thought - maybe I am not precise enough.
actually, I never said that there is no source for dll1. However, it is not
under my control and I
cannot "touch" it.
Code snippets from dll1 code were posted already in this thread:
"
MYDBLib::IDatabaseAccessLayerPtr spDBAccess;
hr = spDBAccess.CreateInstance( MyDBLib::CLSID_DatabaseAccessLayer );
and then calls like
hr = spDBAccess->doSomething(&pbstrMyString1, &pbstrMyString2);
or
hr = spDBAccess->doSomethingElse((BSTR)pbstrParameters, &pbstrOut,
&bstrError);
"
I cannot put the original code in the newsgroup.
The example you posted did not 100% answer how to mimick an existing
interface.
Remember, of dll2 that I want to mimick, I have IDL and I have a TLB, and a
..rgs .
As I said I cannot recompile the dll1 original code against a new tlb (or
even new GUIDs). (I do not know if dll1
actually compiles but that is a different issue - I may have only part of
the source tree)
Since some calls actually happen - but into the wrong methods - I am pretty
solid about that it
must have something must be messed up in the interface order.
The code of dll1, as we have seen, binds against the GUIDs of DLL2 at
compilation time.
My C# dll will have the GUIDs of the original DLL2 (the DLL2 GUIDs I needed
to change, so the .rgs was also changed), so that the DLL1 knows what to call.
Are those types of calls
"hr = spDBAccess->doSomething(&pbstrMyString1, &pbstrMyString2);"
not compiled in a way that the interface is expected to be in a specific
order? Lets forget about
the individual compiler for a second: To know what to do - not thinking of
the language - there are
those ways how to determine what to call (ID shall stand for any type of
symbolic representation,
be it a number, a GUID or a different name, but generated by the compiler
(of dll2) ):
"by method name and order"
"by method name and signature"
"by method name and signature ID"
"by method name and ID"
"by an ID" (unique over method names and signatures)
"by an ID and order"
"by an ID and signature ID" (one ID for the method names, one ID for the
signature)
"by an ID and signature"
"by order"
My guess is that the calls work by order, since there are no duplicated
signatures for the same
method calls, some method calls actually happen but into the wrong methods.
So my question is:
How can I (relatively easily) enforce in a new C# dll that it has the same
interface like an old
C++ DLL (of which I have IDL and TLB). But not try-and-error by comparing
the TLBs.
There _must_ be a documented way on the source code level from (unmanaged,
VC6 or converted to VS2005) C++ IDL (+.rgs) to C#.
Ideally not using tools, but rather going from the IDL source to
the corresponding C# source code step by step. (First we should understand
what to do exactly
before try to use a tool that generates some wrapper that we have to modifiy
but we do not know how
to modify since we do not understand the process to get there).
(Going through .tlb is not on the source code level.)
If this is too hard to find, then I am happy with a relatively simple example.
It should work for a default constructor (ideally also a
finalizer/destructor pairing without diving too deep in all aspects of this -
I am aware that the garbage collector handles the finalizer at different
points in time than destructors get called), 2 methods (so that the suspected
"order"-problem hopefully is addressed - and not just works by coincidence)
and an actual dummy c# implementation of the methods of the interface
(with "void" return types on the C# side)?
Restriction: What I still wanted to use is not to provide explicit HRESULT
return values but use
the "void" return value and have the interop give the proper HRESULT
according to the exception to
the caller.
Thanks,
(If you understand what I mean no need to read further...)
....
Since the example you gave talks about "RCW", I am a little confused,
because that term implies to
talk about a wrapper for a COM assembly that can be called from .NET. Isn't
that the code-basis for the interop.something.dll that is generated when I
add a reference in Visual Studio to a COM-DLL?
(Also - the example there does not seem to mimick the GUIDs of the original
DLL but rather wraps a call to the original DLL in a new DLL with a new GUID.)
However, there is a link in that article:
"
http://msdn2.microsoft.com/en-us/library/k83zzh38(VS.80).aspx"
"
http://msdn2.microsoft.com/en-us/library/xwzy44e4(VS.80).aspx"
I understood the examples all in the way that after following that then have
wrappers for the type library or the DLL
that I then can use from inside the .NET-framework but not to completely
replace a COM interface.
Does the process really mimick the original IDL/DLL/type library (with
keeping the GUIDs to the most possible extend)?
The example in
"
http://msdn2.microsoft.com/en-us/library/x8fbsf00(VS.80).aspx" that you
pointed to does not do
that.
Instead of something like:
" extern int ISATest.InSArray( [MarshalAs(UnmanagedType.SafeArray,
SafeArraySubType=VarEnum.VT_I4)] ref int[] param );
"
Since my types are fairly simply and Visual Studio creates Interop Wrappers
with "out string" parameters and simple types (most complex type - used
rarely - is an ENUM-type).
I would hope to see something like...
....
[someattributes here that can be determined by looking at the IDL]
void MyMethod2(out string someParameterHere,...)
{...
}
[someattributes here]
void MyMethod1(string someParameterHere,out string someparameterthere,...)
{...
}