How to Convert a C++ Structure into C# Structure - c#-2.0

I need to convert a complex C++ structure into C# Structure,I have converted other structures in C#, this one contains some Two Dimensional array that is what the problem how to change it,Here is my structure,
this is other structure, which I Converted properly,
C++:
typedef struct
{
BYTE sSerialNumber[DH_SERIALNO_LEN]; BYTE byAlarmInPortNum;
BYTE byAlarmOutPortNum;
BYTE byDiskNum;
BYTE byDVRType;
BYTE byChanNum;
} NET_DEVICEINFO, *LPNET_DEVICEINFO;
C#:
public struct NET_DEVICEINFO
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 48)]
public byte[] sSerialNumber;
public byte byAlarmInPortNum;
public byte byAlarmOutPortNum;
public byte byDiskNum;
public byte byDVRType;
public byte byChanNum;
}
And This structure Which I want Convert,this has 2 dim Array
C++:
typedef struct
{
DWORD dwSize;
DWORD dwDecProListNum;
char DecProName[DH_MAX_DECPRO_LIST_SIZE][DH_MAX_NAME_LEN];
DH_485_CFG stDecoder[DH_MAX_DECODER_NUM];
DWORD dw232FuncNameNum;
char s232FuncName[DH_MAX_232FUNCS][DH_MAX_NAME_LEN];
DH_RS232_CFG st232[DH_MAX_232_NUM];
} DHDEV_COMM_CFG;
and this is my try in C#,But it is giving me an error,
C#:
[StructLayout(LayoutKind.Sequential, Pack = 2, CharSet = CharSet.Auto)]
public struct DHDEV_COMM_CFG
{
public uint dwSize;
public uint dwDecProListNum;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 100)]
public string[] DecProName;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
DH_485_CFG[] stDecoder;
public uint dw232FuncNameNum;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
public string[] s232FuncName;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public DH_RS232_CFG[] st232;
} ;
Please tell me how to to this....
By Bala

I know this is kinda useless 6 years down the road, but in any case, the converter from here worked nicely for me...

Related

Get data from a metatrader 4 alert

I use an indicator that generates alerts like: eur / USD Buy 1.122323, TP 1.131232, SL 1.114354, my question is how in an EA to read this data to execute the buy order.
cheat engine memory
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using Telegram.Bot;
namespace ConsoleApp45
{
class Program
{
const int PROCESS_WM_READ = 0x0010;
[DllImport("kernel32.dll")]
public static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);
[DllImport("kernel32.dll")]
public static extern bool ReadProcessMemory(int hProcess,
int lpBaseAddress, byte[] lpBuffer, int dwSize, ref int lpNumberOfBytesRead);
public static void Main()
{
string ipek = "";
for (int i = 0; i < 10; i++)
{
Process process = Process.GetProcessesByName("terminal")[0];
IntPtr processHandle = OpenProcess(PROCESS_WM_READ, false, process.Id);
int bytesRead = 0;
byte[] buffer = new byte[10];
//02DD12A4 cheat engine den alınan değer 0x02DD12A4 bu şekilde girilir.
ReadProcessMemory((int)processHandle, 0x02DD12A4, buffer, buffer.Length, ref bytesRead);
string yasin = Encoding.UTF8.GetString(buffer);
}
}
}
}

jna: pass a string from C# to Java

I am using Unamanged dependencies (RGiesecke.DllExport.DllExport) and jna in a small C# function that should return a string consumed within another now java function.
Following the jna suggestions for mapping i crafted the code below:
My C# code:
[RGiesecke.DllExport.DllExport]
public static unsafe char* Test(string id)
{
unsafe
{
fixed (char *s = "test passed")
{
return s;
}
}
}
Java side:
public interface ITest extends Library{
public String Test(String id);
}
public static void main(String[] args) {
ITest nativeExample= (ITest)Native.loadLibrary("C:/native/JavaLib.dll", ITest.class);
String s = nativeExample.Test("id");
System.out.println(s);
}
So, all that is printed, is 't', because I bet all is being transmitted is the address to s[0].
Has anyone had luck mapping strings from C# to java through jna?
Plain strings in the C# code throws errors.
Have you tried returning a string instead of char? or changing char *s to char s[]

how to get JNA read back function's string result

public interface Kernel32 extends StdCallLibrary {
int GetComputerNameW(Memory lpBuffer, IntByReference lpnSize);
}
public class Kernel32Test {
private static final String THIS_PC_NAME = "tiangao-160";
private static Kernel32 kernel32;
#BeforeClass
public static void setUp() {
System.setProperty("jna.encoding", "GBK");
kernel32 = (Kernel32) Native.loadLibrary("kernel32", Kernel32.class);
}
#AfterClass
public static void tearDown() {
System.setProperty("jna.encoding", null);
}
#Test
public void testGetComputerNameW() {
final Memory lpBuffer = new Memory(1024);
final IntByReference lpnSize = new IntByReference();
final int result = kernel32.GetComputerNameW(lpBuffer, lpnSize);
if (result != 0) {
throw new IllegalStateException(
"calling 'GetComputerNameW(lpBuffer, lpnSize)'failed,errorcode:" + result);
}
final int bufferSize = lpnSize.getValue();
System.out.println("value of 'lpnSize':" + bufferSize);
Assert.assertEquals(THIS_PC_NAME.getBytes().length + 1, bufferSize);
final String name = lpBuffer.getString(0);
System.out.println("value of 'lpBuffer':" + name);
Assert.assertEquals(THIS_PC_NAME, name);
}
}
The offical instructions says use byte[]、char[]、Memory or NIO Buffer for mapping char pointer in c native function.But I tried all of above, and String、WString、StringArrays、class extends PointType etc, all of them are no use.
Out parameter 'lpnSize' can return the corret buffer size,but 'lpBuffer' return 'x>'(i think it's random memory) or nothing no matter I mapping any java type.If i wrote someting to the 'lpBuffer' memory first, it would read the same things after calling native function.
How can I solve the problem?
You need to use Pointer.getString(0, true) to extract the unicode string returned by GetComputerNameW.
EDIT
You'll also need to call GetComputerNameW again with the length parameter initialized before the function will fill in the result. Either pass back the same IntByReference to a second call, or initialize the IntByReference to the size of your Memory buffer to have the buffer written to in the first call.

Parameters to use in a Vapi definition for passing arrays by reference

I have the following C code that uses libmodbus to read a single device register using ModbusTCP:
modbus_t *ctx;
uint16_t tab_reg[16];
ctx = modbus_new_tcp("10.0.1.77", 502);
modbus_read_registers(ctx, 0x20, 2, tab_reg);
printf("reg = %d (0x%X)\n", tab_reg[0], tab_reg[0]);
printf("reg = %d (0x%X)\n", tab_reg[1], tab_reg[1]);
now trying to switch this over to Vala using a Vapi that I've generated, the contents of that for new and read are:
[CCode (cheader_filename = "modbus.h", cname = "modbus_new_tcp")]
public static unowned Modbus.modbus_t create_tcp (string ip_address, int port);
public static int read_registers (Modbus.modbus_t ctx, int addr, int nb, uint16 dest);
[CCode (cheader_filename = "modbus.h")]
and the translated Vala program is:
class ModbusReadTest : GLib.Object {
unowned Modbus.modbus_t ctx;
public void run () {
uint16 reg = 0x00;
ctx = create_tcp ("10.0.1.77", 502);
Modbus.read_registers (ctx, 0x20, 2, reg);
message ("reg = %d (0x%X)", reg, reg);
Modbus.close(ctx);
}
}
Coincidentally, when I compile this into C code and then into a binary using gcc I get the error:
read-registers-test.c:71:2: warning: passing argument 4 of ‘modbus_read_registers’ makes pointer from integer without a cast [enabled by default]
which is not surprising. But I'm not sure how I should go about modifying the Vapi contents to closer match the prototype in the libmodbus header:
int modbus_read_registers(modbus_t *ctx, int addr, int nb, uint16_t *dest);
I've tried a mix of array options and using 'out', but haven't been able to get more than a single double byte register at a time.
read_registers should probably be an instance method (on Modbus.modbus_t) instead of a static method, and Modbus.modbus_t should probably be renamed to something like Modbus.Context, create_tcp should probably be a constructor, and Modbus.close should be a free function on the Modbus.Context compact class, but that's beside the point of this question (if you stop by #vala on irc.gnome.org you can get help with that stuff).
You probably want to make it an array:
public static int read_registers (Modbus.modbus_t ctx, int addr, [CCode (array_length_pos = 2.5)] uint16[] dest);
Then you would do something like this in Vala:
public void run () {
uint16 reg[2];
ctx = create_tcp ("10.0.1.77", 502);
Modbus.read_registers (ctx, 0x20, reg);
message ("reg = %d (0x%X)", reg, reg);
Modbus.close(ctx);
}
For a port more faithful to the original C (where tab_reg has 16 elements instead of 2), you could use array slicing:
public void run () {
uint16 reg[16];
ctx = create_tcp ("10.0.1.77", 502);
Modbus.read_registers (ctx, 0x20, reg[0:2]);
stdout.printf ("reg = %d (0x%X)\n", reg, reg);
Modbus.close(ctx);
}
Note that if you make it an instance method you'll need to change the array_length_pos to 1.5.

Retrieving item text with JNA and SendMessage()

I am attempting to retrieve the item text from a Win32 ListView-like control. I am using JNA and SendMessageW() to send LVM_GETITEMTEXTW to the control. I have been successful at retrieving the item count (via LVM_GETITEMCOUNT) but am stumped at this point. My User32 class is setup like so:
public interface MyUser32 extends User32 {
MyUser32 INSTANCE = (MyUser32)Native.loadLibrary("user32", MyUser32.class);
LRESULT SendMessageW(HWND hWnd, int msg, WPARAM wParam, LVITEM lParam);
}
My LVITEM class is setup like so:
public class LVITEM extends Structure{
public LVITEM() {
pszText = new Memory(MEMSIZE);
cchTextMax = MEMSIZE;
}
private static final int MEMSIZE = 256;
public UINT mask;
public int iItem;
public int iSubItem;
public UINT state;
public UINT stateMask;
public Pointer pszText;
public int cchTextMax;
public int iImage;
public LPARAM lParam;
public int iIndent;
protected List<String> getFieldOrder() {
return Arrays.asList(new String[] { "mask", "iItem", "iSubItem", "state", "stateMask", "pszText", "cchTextMax", "iImage", "lParam", "iIndent"});
}
}
And the code that calls it all is like so:
MyUser32 u32 = MyUser32.INSTANCE;
LVITEM lvItem = new LVITEM();
WPARAM wPar = new WPARAM(1);
...
lvItem.iSubItem = 0;
res = u32.SendMessageW(handle, LVM_GETITEMTEXTW, wPar, lvItem);
System.out.println(res.intValue());
s = lvItem.pszText.getString(0);
System.out.println(s);
I've left out a bit of the code but I believe those are the important parts. My issue is that when I print out res.intValue() it is always 0 (meaning no text was returned) and when I print out the string value of pszText it is always some garbage characters. I'm completely stumped at this point so any suggestions are greatly appreciated. Thanks.

Resources