473,385 Members | 2,274 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

c# P/Invoke fails on API method

hi

I just wrote a experiment code that build a DLL that export a method
(ToOut),whic I am trying to call from c#. Right now it return uncorrect
result .

Here is the unmanaged code :

typedef struct flagtest1
{
WORD KK;
}test, *ptest;

typedef struct Out
{
struct
{
DWORD BW: 1;
DWORD Gray: 1;
DWORD Color: 1;

} mode;
ptest pSource[2];
}myOut, * pmyOut;

void ToOut( pmyOut* myouttest)
{

(*myouttest)->mode.BW=1;
(*myouttest)->mode.Color=2;
(*myouttest)->mode.Gray=3;
(*myouttest)->pSource[0] = new test;
(*myouttest)->pSource[1] = new test;
(*myouttest)->pSource[0]->KK=4;
(*myouttest)->pSource[0]->KK=5;
}

Now , here is how I tried the same thing from c#;

[StructLayout(LayoutKind.Explicit,Size=3)]
public class _mode
{
[FieldOffset(0)]
public int BW;

[FieldOffset(1)]
public int Gray;

[FieldOffset(2)]
public int color;
}

[StructLayout(LayoutKind.Sequential)]
public class test
{
public System.UInt16 kk;
}

[StructLayout(LayoutKind.Sequential)]
public class myout
{

public _mode mode;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public IntPtr[] ptest; //=
Marshal.AllocHGlobal(Marshal.SizeOf(typeof(test))) ;

}

public class Program
{
[DllImport("try.dll")]
public static extern void ToOut( out IntPtr test);

public static void Main(string[] args)
{

IntPtr zzz= Marshal.AllocHGlobal(Marshal.SizeOf(typeof(myout)) );
ToOut(out zzz);
myout myzzz = (myout)Marshal.PtrToStructure(zzz, typeof(myout));
/// here the object myzz is uncorrect. the

///members: mode.bw ;mode.gray ;
mode.color and ptest display a random number;

System.Console.WriteLine("{0}",myzzz.mode.BW.ToStr ing());
Marshal.DestroyStructure(zzz, typeof(myout));
Marshal.FreeHGlobal(zzz);
}
}
}

Can anyone suggest a solution?

Thanks

Sep 25 '07 #1
3 1675
"philipqiu" <qi*****@gmail.comwrote in message
news:%2****************@TK2MSFTNGP05.phx.gbl...
hi

I just wrote a experiment code that build a DLL that export a method
(ToOut),whic I am trying to call from c#. Right now it return uncorrect
result .

Here is the unmanaged code :

typedef struct flagtest1
{
WORD KK;
}test, *ptest;

typedef struct Out
{
struct
{
DWORD BW: 1;
DWORD Gray: 1;
DWORD Color: 1;

} mode;
ptest pSource[2];
}myOut, * pmyOut;

void ToOut( pmyOut* myouttest)
{

(*myouttest)->mode.BW=1;
(*myouttest)->mode.Color=2;
(*myouttest)->mode.Gray=3;
(*myouttest)->pSource[0] = new test;
(*myouttest)->pSource[1] = new test;
(*myouttest)->pSource[0]->KK=4;
(*myouttest)->pSource[0]->KK=5;
}

Now , here is how I tried the same thing from c#;

[StructLayout(LayoutKind.Explicit,Size=3)]
public class _mode
{
[FieldOffset(0)]
public int BW;

[FieldOffset(1)]
public int Gray;

[FieldOffset(2)]
public int color;
}

[StructLayout(LayoutKind.Sequential)]
public class test
{
public System.UInt16 kk;
}

[StructLayout(LayoutKind.Sequential)]
public class myout
{

public _mode mode;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public IntPtr[] ptest; //=
Marshal.AllocHGlobal(Marshal.SizeOf(typeof(test))) ;

}

public class Program
{
[DllImport("try.dll")]
public static extern void ToOut( out IntPtr test);

public static void Main(string[] args)
{

IntPtr zzz=
Marshal.AllocHGlobal(Marshal.SizeOf(typeof(myout)) );
ToOut(out zzz);
myout myzzz = (myout)Marshal.PtrToStructure(zzz,
typeof(myout)); /// here the object myzz is uncorrect. the

///members: mode.bw ;mode.gray ; mode.color and ptest display a random
number;

System.Console.WriteLine("{0}",myzzz.mode.BW.ToStr ing());
Marshal.DestroyStructure(zzz, typeof(myout));
Marshal.FreeHGlobal(zzz);
}
}
}

Can anyone suggest a solution?

Thanks

Several things are fundamentaly wrong with this code.
First at the C side....
1) When you allocate memory from the unmanaged heap (AllocHGlobal), you are
responsible for clearing that memory before use.
That means you need to use something like :
SecureZeroMemory(*myouttest, sizeof(*myouttest));
in your C code before filling the structure.
2) Bitfields in C are not layd-out as you may think. Your struct mode is one
DWORD (4 bytes long) in C, and your BW, Color and Gray fields are one bit
each. You are moving 2 and 3 to Color and Gray respectively, but they are
one single bit, so the result is not really what you might expect. You can
only move 0 or 1 to single bit fields....

Second your C# code.
Here your _mode declares an overlapping construct of three int's. The first
int start at byte displacement 0, the second at displacement 1 and the third
at 2. That means that your class is 6 bytes in total, not really what your C
code is expecting from this struct.
What you should do is declare this field in myOut as an int (1), or
redeclare _mode as an enum (2).

1)
[StructLayout(LayoutKind.Sequential)]
public class myout
{
public int mode;
...

2)
[Flags]
public enum _mode
{
BW = 0x01,
Gray = 0x02,
Color = 0x04
}

[StructLayout(LayoutKind.Sequential)]
public class myout
{
public _mode mode;
...

Willy.
Sep 25 '07 #2
Thanks
"Willy Denoyette [MVP]" <wi*************@telenet.be>
??????:u0**************@TK2MSFTNGP05.phx.gbl...
"philipqiu" <qi*****@gmail.comwrote in message
news:%2****************@TK2MSFTNGP05.phx.gbl...
>hi

I just wrote a experiment code that build a DLL that export a method
(ToOut),whic I am trying to call from c#. Right now it return uncorrect
result .

Here is the unmanaged code :

typedef struct flagtest1
{
WORD KK;
}test, *ptest;

typedef struct Out
{
struct
{
DWORD BW: 1;
DWORD Gray: 1;
DWORD Color: 1;

} mode;
ptest pSource[2];
}myOut, * pmyOut;

void ToOut( pmyOut* myouttest)
{

(*myouttest)->mode.BW=1;
(*myouttest)->mode.Color=2;
(*myouttest)->mode.Gray=3;
(*myouttest)->pSource[0] = new test;
(*myouttest)->pSource[1] = new test;
(*myouttest)->pSource[0]->KK=4;
(*myouttest)->pSource[0]->KK=5;
}

Now , here is how I tried the same thing from c#;

[StructLayout(LayoutKind.Explicit,Size=3)]
public class _mode
{
[FieldOffset(0)]
public int BW;

[FieldOffset(1)]
public int Gray;

[FieldOffset(2)]
public int color;
}

[StructLayout(LayoutKind.Sequential)]
public class test
{
public System.UInt16 kk;
}

[StructLayout(LayoutKind.Sequential)]
public class myout
{

public _mode mode;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public IntPtr[] ptest; //=
Marshal.AllocHGlobal(Marshal.SizeOf(typeof(test)) );

}

public class Program
{
[DllImport("try.dll")]
public static extern void ToOut( out IntPtr test);

public static void Main(string[] args)
{

IntPtr zzz=
Marshal.AllocHGlobal(Marshal.SizeOf(typeof(myout) ));
ToOut(out zzz);
myout myzzz = (myout)Marshal.PtrToStructure(zzz,
typeof(myout)); /// here the object myzz is uncorrect. the

///members: mode.bw ;mode.gray ; mode.color and ptest display a random
number;

System.Console.WriteLine("{0}",myzzz.mode.BW.ToStr ing());
Marshal.DestroyStructure(zzz, typeof(myout));
Marshal.FreeHGlobal(zzz);
}
}
}

Can anyone suggest a solution?

Thanks


Several things are fundamentaly wrong with this code.
First at the C side....
1) When you allocate memory from the unmanaged heap (AllocHGlobal), you
are responsible for clearing that memory before use.
That means you need to use something like :
SecureZeroMemory(*myouttest, sizeof(*myouttest));
in your C code before filling the structure.
2) Bitfields in C are not layd-out as you may think. Your struct mode is
one DWORD (4 bytes long) in C, and your BW, Color and Gray fields are one
bit each. You are moving 2 and 3 to Color and Gray respectively, but they
are one single bit, so the result is not really what you might expect. You
can only move 0 or 1 to single bit fields....

Second your C# code.
Here your _mode declares an overlapping construct of three int's. The
first int start at byte displacement 0, the second at displacement 1 and
the third at 2. That means that your class is 6 bytes in total, not really
what your C code is expecting from this struct.
What you should do is declare this field in myOut as an int (1), or
redeclare _mode as an enum (2).

1)
[StructLayout(LayoutKind.Sequential)]
public class myout
{
public int mode;
...

2)
[Flags]
public enum _mode
{
BW = 0x01,
Gray = 0x02,
Color = 0x04
}

[StructLayout(LayoutKind.Sequential)]
public class myout
{
public _mode mode;
...

Willy.


Sep 26 '07 #3
hi

The unmanaged code is as follows:
typedef struct tagstructtest1
{
DWORD dwon;
}structtest1, * pstructtest1 ;

typedef struct tagstructtest
{
DWORD dwone;
structtest1 two;
}structtest, *pstructtest ;

void teststruct( pstructtest pmytest)
{
pmytest = new structtest;
ZeroMemory(pmytest, sizeof(pmytest));
pmytest->dwone=999;
pmytest->two.dwon=123456;
}

Sep 27 '07 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Tom | last post by:
Hi Everybod I want to update some controls in a form from another threads. I did it by passing the form to that thread and calling a delegate with Form1.Invoke, I want to have just one delegeate...
5
by: RickDee | last post by:
Please help, anybody. I am trying to write a program so that it can launch an exe file ( which is also genereated in C# ) and then simulate the button clicking and invoke the methods inside the...
14
by: stic | last post by:
Hi, I'm in a middle of writing something like 'exception handler wraper' for a set of different methodes. The case is that I have ca. 40 methods form web servicem, with different return values...
0
by: Ken Yee | last post by:
Anyone know how to do this in C#? It's pretty trivial in VB, but is being a PITA in C#. I can call the Start/Stop methods w/o any problems, but I can't figure out how to read the current status...
2
by: John Lutz | last post by:
Our app is mainly COM based. We allow .NET plug-ins. When a plug-in is installed, it receives a COM pointer to the app. The plug-in implements our IExtensionImpl interface and gets the app...
4
by: igd | last post by:
I am forced to decorate my .NET Main()-method with , since an unmanaged function (which i am calling through P/Invoke) calls CoCreateInstance() in turn. The problem is, that another unmanaged...
6
by: Dom | last post by:
I'm teaching myself about delegates and the Invoke method, and I have a few newbie questions for the gurus out there: Here are some CSharp statements: 1. public delegate void MyDelegate (int k,...
3
balabaster
by: balabaster | last post by:
I have a class that I want to make thread-safe and am investigating the ISyncronizeInvoke interface and wondering just what it will take to implement this interface. So far the basic concept of my...
5
by: rafal.m | last post by:
Hi This code fails: class K2 { public function increment(&$obj) { $obj += 1; }
2
by: rdilipk | last post by:
I am posting at the end of this post some code that P/Invoke's SetSystemTime to set the local system time. This call fails -- i.e the time is not set and the API returns false. However calling...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.