Microsoft KB Archive/325742

= HOW TO: Implement .NET COM Interfaces that Require ByRef Parameters =

Article ID: 325742

Article Last Modified on 8/15/2005

-

APPLIES TO


 * Microsoft Visual J# .NET 2003 Standard Edition

-



This article was previously published under Q325742



IN THIS TASK
SUMMARY
 * View the COM Interface in MSIL
 * Change the MSIL Method Declaration
 * Reassemble, Implement, and Compile the Interface
 * Notes About Registration
 * Troubleshooting



SUMMARY
This step-by-step article describes how to implement a Microsoft .NET COM interface with methods that take parameters by reference in Visual J# .NET. A Java language dictum prevents direct implementation of such methods, so you must manually edit the Microsoft intermediate language (MSIL) code.

back to the top

View the COM Interface in MSIL
Consider the following interface definitions in Interface Definition Language (IDL): import &quot;oaidl.idl&quot;; import &quot;ocidl.idl&quot;;

[   object, uuid(8BDC1D4F-94B3-4a99-AE01-2B40B5A5DA67) ] interface IMyInterface : IDispatch { HRESULT ShowFace; };

[   object, uuid(26994F59-B3C3-4681-97D4-583EF892F46A) ] interface RefInterface : IDispatch { HRESULT RefMethod([in, out] int *num); HRESULT MarshalInterfaceToCOM([in] IMyInterface *pI); };

[   uuid(09BC59B9-7C65-4B85-8073-42F404EEA3CA) ] library ByRefLib { interface RefInterface; interface IMyInterface; }; To view the intermediate language for this COM type description, compile to a COM type library and convert it to MSIL wrappers by using the TlbImp.exe tool. The following is a sample batch file that uses these COM type definitions. The last line opens a text file of MSIL instructions and metadata for the COM interface .NET wrappers. midl /client none /server none ByRefLib.idl del *.c *.h tlbimp ByRefLib.tlb /namespace:Interop.ByRefLib ildasm ByRefLib.dll /out=tmp.il notepad tmp.il The following is a sample of the MSIL code that represents the method declaration: .method public hidebysig newslot virtual abstract instance void RefMethod([in][out] int32& num) runtime managed internalcall back to the top

Change the MSIL Method Declaration
In Notepad or a similar text editor, open the output file from the ildasm command (tmp.il in this example), and then find the RefMethod signature declaration line in the class member declarations section. It will look similar to the following: instance void RefMethod([in][out] int32& num) runtime managed internalcall This is the line that you must change to enable implementation of the interface in the Java language on .NET. Edit this line so that it matches the following: instance void RefMethod([in][out] int32[] marshal([]) num) cil managed back to the top

Reassemble, Implement, and Compile the Interface
Now you are ready to reassemble the modified MSIL code so that you have a compatible wrapper class to use in a Visual J# .NET implementation. To do this, use the Ilasm.exe tool. The following sample batch completes the reassembly, build, and registration steps to create a sample Java language implementation of these COM interfaces. sn -k devkey.snk ilasm /dll /output=ByRefLib.dll /key=devkey.snk tmp.il vjc Class1.jsl /r:mscorlib.dll /r:ByRefLib.dll /t:library /out:ComImpl.dll regasm ComImpl.dll /codebase /registered //Class1.jsl

import System.Runtime.InteropServices.*; import System.Reflection.*;

/** @assembly AssemblyKeyFile(&quot;devkey.snk&quot;) */ /** @attribute ClassInterface(ClassInterfaceType.None) */ /** @attribute GuidAttribute(&quot;AFF464D1-7CD5-42b6-8AC6-3F8C292817C3&quot;) */

public class COMImpl implements Interop.ByRefLib.RefInterface, Interop.ByRefLib.IMyInterface { public void RefMethod(int[] num) {   num[0] = (-1)*num[0]; }

public void MarshalInterfaceToCOM(   Interop.ByRefLib.IMyInterface pI) {   pI.ShowFace; }

public void ShowFace {   com.ms.win32.User32.MessageBox(      0,       this.GetType.ToString,       &quot;ShowFace&quot;,       0); } } back to the top

Notes About Registration
Notice the /registered switch on the Regasm tool. With Regasm, you register managed implementations for exposure to COM. Errors occur if you try to register managed types that wrap COM types, as in this scenario. In other words, you cannot use Regasm to register TlbImp-generated .NET wrappers. However, in this case, you must register the CoClass for your implementation. To avoid the errors from the COM definitions that you import in this example, use the /registered switch.

Also notice the reference to the Devkey.snk file. This is a temporary key pair that is used to sign the assembly. Although it is not required, it is generally assumed that managed COM implementations are eventually destined for the global assembly cache, which requires a strong name. Signing the assembly in this way gives the assembly a strong name, which can also help you to avoid signing-related error messages.

back to the top

Troubleshooting
If you try to implement a TlbImp-generated wrapper interface that includes ByRef parameters without the workaround that is discussed in this article, you may receive the following error message in the compiler:

Class1.jsl(11,8): error VJS1169: 'COMImpl' must be declared abstract or 'Interop.ByRefLib.RefInterface.RefMethod(byref int)' must be implemented.

The following sample Microsoft Visual Basic 6.0 client code shows an integer value that has been changed by the server. Private Sub Command1_Click

Dim iface1 As RefInterface Set iface1 = CreateObject(&quot;COMImpl&quot;)

Dim var1 As Long Let var1 = 1 iface1.RefMethod var1 MsgBox var1

iface1.MarshalInterfaceToCOM iface1

End Sub back to the top

Additional query words: vjsharp jsharp j# byref com

Keywords: kbhowto kbhowtomaster KB325742

-

[mailto:TECHNET@MICROSOFT.COM Send feedback to Microsoft]

© Microsoft Corporation. All rights reserved.