[lnkForumImage]
TotalShareware - Download Free Software

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


 

ZhangZQ

11/1/2003 2:11:00 PM

I created a ocx that has a method,

[id(5), helpstring("·½·¨Test1")] void Test1(VARIANT* a);

the implementation is
void Cocx030820Ctrl::Test1(VARIANT* a)
{
try
{
//see here
AFX_MANAGE_STATE(AfxGetStaticModuleState());

ST_PRINT* m;
//get data
m=(ST_PRINT*)a;
CString s;
s.Format("%d,%d,%s,%c",m->i,m->l,m->s,m->mSTRU1.c);
MessageBox(s);
}
catch(...)
{
MessageBox("f");
}
}

and the ST_PRINT definition is

#ifndef IOPRINT
#define IOPRINT
typedef struct
{
unsigned char a[11];
unsigned char b[9];
char c;
}STRU1;

typedef struct
{
unsigned char Tran[11];
unsigned char TermId[9];
STRU1 mSTRU1;
char c;
int i;
long l;
double d;
char s[10];
}ST_PRINT;

#endif

My question is how to call the Test1 method in C#
//ST_PRINT
object obj=new object();
how can I set the field value of obj.
axocx0308201.Test1(ref b3);




Thank you very much!


4 Answers

(Mattias Sjögren)

11/3/2003 8:38:00 PM

0


>the implementation is
>void Cocx030820Ctrl::Test1(VARIANT* a)
>{
> try
> {
> //see here
> AFX_MANAGE_STATE(AfxGetStaticModuleState());
>
> ST_PRINT* m;
> //get data
> m=(ST_PRINT*)a;

These kinds of hacks might work in C++, but not in C#. Why do you make
the parameter type a VARIANT* when it really isn't?



Mattias

--
Mattias Sjögren [MVP] mattias @ mvps.org
http://www.msjogren.n...
Please reply only to the newsgroup.

ZhangZQ

11/3/2003 11:01:00 PM

0

Dear Mattias,

It is necessary, because that OCX is the third party product, I have to use
it but can not change it, is it possible to do that?

Thank you very much!


ZhangZQ


"Mattias Sjögren" <mattias.dont.want.spam@mvps.org> wrote in message
news:eZShNpkoDHA.688@TK2MSFTNGP10.phx.gbl...
>
> >the implementation is
> >void Cocx030820Ctrl::Test1(VARIANT* a)
> >{
> > try
> > {
> > //see here
> > AFX_MANAGE_STATE(AfxGetStaticModuleState());
> >
> > ST_PRINT* m;
> > //get data
> > m=(ST_PRINT*)a;
>
> These kinds of hacks might work in C++, but not in C#. Why do you make
> the parameter type a VARIANT* when it really isn't?
>
>
>
> Mattias
>
> --
> Mattias Sjögren [MVP] mattias @ mvps.org
> http://www.msjogren.n...
> Please reply only to the newsgroup.


Daniel

11/6/2003 2:42:00 PM

0

First of all, I think Mattias has a point when he states
that the code you showed is a hack ;) Code like that
should ALWAYS be avoided ...

ok, here is a short howto :) it is hard and by the look of
your previous questions you will have a hard time
following the trail at all times but give it a try ;)

1. You can't use tlbimp to create your interop
assembly, you have to write it by hand. This is to avoid
the problem that tlb converts all VARIANT to objects and
then the standard .net marshalling handles all conversion,
which won't work in your ugly hack ;)
When defining the methods that take an VARIANT in the OCX
make sure that theese parameters are IntPtr instead.

2. Define a .NET type with the same binary layout as the
ST_PRINT. Look at interop in msdn for samples.

3. Instanciate the OCX object with the Activator.

4. instanciate the .NET ST_PRINT type and set the
paramters.

5. Pin the ST_PRINT object using GCHandle.Alloc( obj,
Pinned ) [note psuedocode is is slightly different in real
life)

6. cast the object from the activator into the interface
that you defined in #1.

7. call the method with the result from
handle.AddrOfPinnedObj() as the VARIANT parameter.

8. free the pinned object

neither of these steps are simple or straight forward.
I have been working with .NET since the release of beta
and I'm not certain that I would be able to make it work
without a LOT of trouble. So how should you do it then?
I would create a COM component that encapsulates the ocx
but with proper and hackfree interfaces. Then I would use
this component instead. Does this solution have any
drawbacks? Yes there will be one more level of
indirection, but compared to the pain of making it work
in .NET that cost is SMALL ;)

Best Regards,
Daniel

Lowlevel hack ;) don't try this at home...
ps. maybe you could use tlbimp to generate the
interopassembly. Then use ildsam to disassemble it into IL
code. Edit this code so that the objects are changed to
IntPtr, compile into an assembly using ilasm.
- this might work, but it is even more risky and hard...


>-----Original Message-----
>Dear Mattias,
>
>It is necessary, because that OCX is the third party
product, I have to use
>it but can not change it, is it possible to do that?
>
>Thank you very much!
>
>
>ZhangZQ
>
>
>"Mattias Sjögren" <mattias.dont.want.spam@mvps.org> wrote
in message
>news:eZShNpkoDHA.688@TK2MSFTNGP10.phx.gbl...
>>
>> >the implementation is
>> >void Cocx030820Ctrl::Test1(VARIANT* a)
>> >{
>> > try
>> > {
>> > //see here
>> > AFX_MANAGE_STATE(AfxGetStaticModuleState());
>> >
>> > ST_PRINT* m;
>> > //get data
>> > m=(ST_PRINT*)a;
>>
>> These kinds of hacks might work in C++, but not in C#.
Why do you make
>> the parameter type a VARIANT* when it really isn't?
>>
>>
>>
>> Mattias
>>
>> --
>> Mattias Sjögren [MVP] mattias @ mvps.org
>> http://www.msjogren.n...
>> Please reply only to the newsgroup.
>
>
>.
>

(Mattias Sjögren)

11/19/2003 12:40:00 PM

0


>It is necessary, because that OCX is the third party product, I have to use
>it but can not change it, is it possible to do that?

Only if you change the managed definition of the method to take an
IntPtr or a ST_PRINT& parameter instead.



Mattias

--
Mattias Sj&#246;gren [MVP] mattias @ mvps.org
http://www.msjogren.n...
Please reply only to the newsgroup.