Hi,
I felt so lucky to find this discussion dated of Aug. 1st, because we are
having a similar problem. But as I tried a couple of times following the
steps carefully, only failed to work it out.( I modified the RCW wrapper's IL
file instead of the Windows Forms callable wrapper's IL file, because we are
modifing its source code already.)
Our problem domain: use MFC ActiveX Control project to create the ActiveX
control,
passing image data array or a memory block from C# to the ActiveX control
for it to process and then get the data back.
The discussion first suggested using System.IntPtr for the parameter type,
but that caused "Type mismatch" ComException. Then System.Int32 is suggested
instead, but I still has the same error.
In the end, I tried to use LONG type in the interface declaration, but I was
unable to do static cast to a pointer in the C++ side.
I know I must have done something wrong, just don't see where.
Any help is highly appreciated.
Liping
==================================================
Original dicussion:
Hi Sidney,
Sorry, I was not aware of this is an ActiveX control and you need add it to
the toolbox,
So here are the steps with some changes:
1. use aximp to generate the interop wrapper assemblies
aximp imageOCX.ocx /source
it will generate one C# source file and two wrapper assemblies.
2. open the AxImageOcxLib.cs file in your favorite text editor, change the
parameter type in the definition ImageProcess method to System.IntPtr.
Note, you need also add [System.ComponentModel.ToolboxItemAttribute (true)]
attribute to the AxImageOCX class, aximp by default will not add this
attribute so that the controls in the generated assembly will not show up
in the toolbox.
3. dis-assembly the wrapper assembly AxImageOCXLib.dll into IL code using
ILDasm
ildasm /all /out:newWrapper.il newWrapper.dll
4. open the .il code file in a text editor and find the ImageProcess
method. find the ImageProcess method defintion, change the parameter type
from "unsigned int8&" to "native int". Note the method definition may
appear several times because several some wrapper class will inherite this
interface and override the method, you need change the type in all the
definitions.
5. save the il file and compile it using ilasm, you may need to generate
the debug version and the release version wrappers.( /Debug option for
debug version).
ilasm /DLL /DEBUG /RESOURCE=ImageOCXLib.res ImageOCXLib.il
then we get the modified ImageOCXLib.dll
6. compile the C# code file to generate the ActiveX control wrapper
assembly, AxImageOCXLib.dll, accordingly you may use /debug+ and reference
the debug version of ImageOCXLib.dll to generate the debug build.
csc /target:library /debug+ /reference:ImageOCXLib.DLL AxImageOCXLib.cs
If the compile is ok, we should get the output assembly AxImageOCXLib.dll
7. in your project, select "Add/Remove items.." from the context menu of
ToolBox,
In .NET Tab click "Browser" button to select the modified
AxImageOCXLib.dll
then drag the toolitem onto the Form. Since VS.NET IDE think this is a .NET
control it will not generate the wrapper class automatically.
Feel free to let me know if you meet any problem when following the steps
above.
In addition, if you need add a strong name key to the generated wrapper,
you may add /KEY option when using ilasm, and add the [assembly:
System.Reflection.AssemblyKeyFileAttribute( ...)] in the C# source file.
Thanks!
Best regards,
Ying-Shen Yu [MSFT]
Microsoft Community Support
Get Secure! - www.microsoft.com/security
Liping - 02 Oct 2004 02:23 GMT
Updated with some correction:
Our problem domain: use MFC ActiveX Control project wizard to create the
ActiveX control,
passing image data array or a memory block from C# to the ActiveX control
for it to process and then get the data back.
What I did:
1. Use aximp.exe to generate two wapper assemblies and one source code for
Windows Forms wrapper from the ActiveX control .tlb or .ocx file
2. Modify the paramter to type "ref System.Int32".(Right ?)
3. Use csc.exe to reassemble Windows Forms wrapper assembly with unchanged
RCW assembly and the modified Windows Forms wrapper source code.
4. Add the wrapped ActiveX control to toolbox
5. Use the following C# code to call the control:
int [] ar = new int[5];
for(int i = 0; i < 5; i++)
ar[i] = i;
axAa1.PutData(5, ref ar[0]);
The call went through ok, but at the control end:
void CAaCtrl::PutData(long nCnt, long FAR* pBuf)
{
char buf[8];
FILE *fp = fopen("data.log", "w+t");
for (int i = 0; i < nCnt; i ++)
{
sprintf(buf, "%d\n", pBuf[i]);
fwrite(buf, strlen(buf), 1, fp);
}
fclose(fp);
}
I found the unexpected data in the "data.log", instead of "0, 1, 2, 3, 4".
In the end, I tried to use LONG type(actually just "long") in the interface
declaration, but I was unable to do static cast to a pointer in the C++ side.
The compiler complains:
error C2440: 'static_cast' : cannot convert from 'long' to 'long *'
Conversion from integral type to pointer type requires
reinterpret_cast, C-style cast or function-style cast
I know I must have done something wrong, please help.
Liping
==================
> Hi,
>
[quoted text clipped - 85 lines]
> Microsoft Community Support
> Get Secure! - www.microsoft.com/security
Liping - 06 Oct 2004 01:28 GMT
Never mind. I figured it out.
> Updated with some correction:
>
[quoted text clipped - 142 lines]
> > Microsoft Community Support
> > Get Secure! - www.microsoft.com/security