Windows Vista Forums
Vista Forums Home Join Vista Forums Windows 7 Forum Vista Tutorials Tags
Welcome to Windows Vista Forums. Our forum is dedicated to helping you find solutions with any problems, errors or issues you are experiencing with Windows Vista. The Vista forum also covers news and updates and has an extensive Windows Vista tutorial section that covers a wide range of tips and tricks.

Go Back   Vista Forums > Misc Newsgroups > .NET General

Vista - COM Interop with ActiveX nightmare...

Reply
 
Old 06-01-2009   #1 (permalink)
Wizfrog


 
 

COM Interop with ActiveX nightmare...

Hello and thanks for reading...

I am using a C++ unmanaged ActiveX (ocx) that allows me to read a
specific file format, and get data out of those.

I use C# .Net.
To use the ActiveX, I simply added it to my toolbox, and create an
instance in a form. Until there, all is good. I can read files, get
the data etc... even if I need to 'copy' the data from the unmanaged
side to the managed side.

Now where I hit a rodblock is when I try to copy the data back to the
ActiveX:
I need to pass a float[] to the COM object to then 'save' the data in
the original (proprietary) file format.
The ActiveX function in C++ is defined as

PutValue(int dataID, float* parray, uint size)

however in C#, the converted function by the ActiveX importer becomes

PutValue(int dataID, ref float parray, int size)

All the research I've done to figure out a solution leads me to
conclude that I need to Marshal the float* parameter into "IntPtr"

That's where I am stuck:
The imported library is already in managed C#, and shows as non-
editable 'MetaData', and it doesn't seem like I can override an
Interface declaration. So I don't see a way to Marshal the parameter.

So I tried to use COM interop directly, by calling the ActiveX.ocx
using [DllImport]

[DllImport(@"MyACTIVEX.ocx", EntryPoint = "#3")]
[return] int ID public static extern int Load(string
filename);

[DllImport(@"MyACTIVEX.ocx", EntryPoint = "#60")]
public static extern int PutValueEx(int ID, IntPtr pt, int
size);

I first had to figure out the entry point # in order to access the
functions, but got so far.
Now, calling the ocx directly, I get "Attempted to read or write
protected memory" error when trying to load the file.

Obviously there is something else that's being done when importing an
ActiveX through the toolbox.


I also tried to import the library directly, using AXIMP.EXE
It created 2 DLLs. One seems to be the managed interop library I can
get the code from if I use the "/source" tag, the other is the actual
COM DLL.

Problem, if I reference the 1st DLL, or import the source in my
project, I see that it calls the second DLL that includes the actual
functions.
So I tried to use [DllImport] directly on that second DLL, but there
it is not able to find an entry point.

Using LibDump, I could see the type library information from the ocx
file, but I can't see anything one either of the 2 DLLs generated,
which leads me to think they are missing the interface definition.

So, I'm trying to figure out a way out of this mess:
Either by finding a way to override the interface in the imported
ActiveX control from the toolbox, and marshal the paramter properly
Or
By finding the way to generate the DLL properly so I can import it
directly with [DllImport]
Or
figure out what is wrong when calling the .ocx file directly with
[DllImport]

Any suggestion would be greatly appreciated.


Note:
1) I do not need any of the 'control' form features, only to load the
file, read the data, put data back in and save it.
2) I did ask the vendor for the file format, so I could read/write it
directly in C#, but I didn't get anywhere. Would have been my
preference but this is not an option.

My System SpecsSystem Spec
Old 06-04-2009   #2 (permalink)
G Himangi


 
 

Re: COM Interop with ActiveX nightmare...

I dont think the ActiveX would be exporting the method directly via ordinal,
they typically provide an interface though which you call the methods.

You could try declaring the interface yourself and then getting an instance
to that interface by using CoCreateInstance via p/Invoke (or
CoGetClassObject and then creating the instace).

---------
- G Himangi, LogicNP Software http://www.ssware.com
Shell MegaPack: Drop-In GUI Controls For Windows Explorer Like File And
Folder Browser Functionality
CryptoLicensing: Add licensing, copy-protection and activation to your
software
EZNamespaceExtensions: Fast and painless development of namespace extensions
EZShellExtensions: Rapid development of all shell extensions,explorer bars
and BHOs
---------


"Wizfrog" <googleaccount@xxxxxx> wrote in message
news:42f17886-03cb-4ef5-b2ef-93b5d5b508c4@xxxxxx
Quote:

> Hello and thanks for reading...
>
> I am using a C++ unmanaged ActiveX (ocx) that allows me to read a
> specific file format, and get data out of those.
>
> I use C# .Net.
> To use the ActiveX, I simply added it to my toolbox, and create an
> instance in a form. Until there, all is good. I can read files, get
> the data etc... even if I need to 'copy' the data from the unmanaged
> side to the managed side.
>
> Now where I hit a rodblock is when I try to copy the data back to the
> ActiveX:
> I need to pass a float[] to the COM object to then 'save' the data in
> the original (proprietary) file format.
> The ActiveX function in C++ is defined as
>
> PutValue(int dataID, float* parray, uint size)
>
> however in C#, the converted function by the ActiveX importer becomes
>
> PutValue(int dataID, ref float parray, int size)
>
> All the research I've done to figure out a solution leads me to
> conclude that I need to Marshal the float* parameter into "IntPtr"
>
> That's where I am stuck:
> The imported library is already in managed C#, and shows as non-
> editable 'MetaData', and it doesn't seem like I can override an
> Interface declaration. So I don't see a way to Marshal the parameter.
>
> So I tried to use COM interop directly, by calling the ActiveX.ocx
> using [DllImport]
>
> [DllImport(@"MyACTIVEX.ocx", EntryPoint = "#3")]
> [return] int ID public static extern int Load(string
> filename);
>
> [DllImport(@"MyACTIVEX.ocx", EntryPoint = "#60")]
> public static extern int PutValueEx(int ID, IntPtr pt, int
> size);
>
> I first had to figure out the entry point # in order to access the
> functions, but got so far.
> Now, calling the ocx directly, I get "Attempted to read or write
> protected memory" error when trying to load the file.
>
> Obviously there is something else that's being done when importing an
> ActiveX through the toolbox.
>
>
> I also tried to import the library directly, using AXIMP.EXE
> It created 2 DLLs. One seems to be the managed interop library I can
> get the code from if I use the "/source" tag, the other is the actual
> COM DLL.
>
> Problem, if I reference the 1st DLL, or import the source in my
> project, I see that it calls the second DLL that includes the actual
> functions.
> So I tried to use [DllImport] directly on that second DLL, but there
> it is not able to find an entry point.
>
> Using LibDump, I could see the type library information from the ocx
> file, but I can't see anything one either of the 2 DLLs generated,
> which leads me to think they are missing the interface definition.
>
> So, I'm trying to figure out a way out of this mess:
> Either by finding a way to override the interface in the imported
> ActiveX control from the toolbox, and marshal the paramter properly
> Or
> By finding the way to generate the DLL properly so I can import it
> directly with [DllImport]
> Or
> figure out what is wrong when calling the .ocx file directly with
> [DllImport]
>
> Any suggestion would be greatly appreciated.
>
>
> Note:
> 1) I do not need any of the 'control' form features, only to load the
> file, read the data, put data back in and save it.
> 2) I did ask the vendor for the file format, so I could read/write it
> directly in C#, but I didn't get anywhere. Would have been my
> preference but this is not an option.

My System SpecsSystem Spec
Old 06-04-2009   #3 (permalink)
WizzZZ


 
 

Re: COM Interop with ActiveX nightmare...


Someobdy suggested this:

You'll have to do some manual work to change the parameter type from ref
float to float[]. The procedure is described here
http://msdn.microsoft.com/en-us/library/ek1fb3c6.aspx

Which i followed but not I am stuck with this:

I managed to generate the tlb file with tlbimp, Changed the MSIL,
reassembled and got a DLL

now I'm trying to use it and even though I added it as a reference, I get a
'FileNotFoundException' when running.

it is looking for a filename:
"myactivexassembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
which is not the filename, so I am guessing it is looking up the DLL in the
registry and can't find it.

I tried to register the dll with regsvr32, but it says "no entry point was
found, cannot register dll.

I am told that to be registered, it needs to be a COM object, but obviously
after changing the MSIL, it is not, I guess.

So what else do I need to do from here?

also, if I wanted to use it as an actual activex, to import in my toolbox
and use in a form, how do I generate an ActiveX?
the dll generated is not an activeX, and cannot be imported in the toolbox.

Thanks for help.
My System SpecsSystem Spec
Reply

Thread Tools


Similar Threads
Thread Forum
Interop .NET General
Microsoft.VirtualServer.Interop.dll and the Microsoft.VMRCClientControl.Interop.dll Virtual Server
To Reference Interop.XXX.dll or XXX.dll .NET General
Using an interop assembly with interop dependencies PowerShell
ActiveX Control prompt "An ActiveX control on this page might be u Vista General


Vista Forums is an independent web site and has not been authorized,
sponsored, or otherwise approved by Microsoft Corporation.
"Windows Vista", the Start Orb, and related materials are trademarks of Microsoft Corp.
© Designer Media Ltd

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46