473,396 Members | 1,891 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,396 software developers and data experts.

Platform invoke: referencing parameters as structures

Russ here. I'm new to this forum. I need help in understanding why
the following code does not work. Basically, I'm defining a
structure in a c# application, and using a c++ dll to modify it.

Here's the c++ .dll file:

// DemoAccountDLLTest.cpp : Defines the entry point for the DLL
application.
//

#include "stdafx.h"
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}

struct DemoAccountInfo
{
int login;
char password[16];
char phonepassword[16];
char name[64];
char group[16];
char country[32];
char city[32];
char state[32];
char zipcode[16];
char address[32];
char phone[32];
char email[32];
char unused[72];
int leverage;
double balance;
char reserved[20];
};

extern "C" __declspec(dllexport) void __stdcall
OpenDemoAccount(DemoAccountInfo *info)
{
info->login = 123456;
strcpy(info->password, "a1b2c3d4");
}

Here's the c# console application:

using System;
using System.Runtime.InteropServices;

namespace ConsoleApplication2
{
/// <summary>
/// Summary description for Class1.
/// </summary>
class Class1
{
[DllImport("DemoAccountDLLTest.dll")]
public static extern void OpenDemoAccount(out DemoAccountInfo
info);

[StructLayout(LayoutKind.Sequential)]
public struct DemoAccountInfo
{
public int login;
public char[] password;
public char[] phonepassword;
public char[] name;
public char[] group;
public char[] country;
public char[] city;
public char[] state;
public char[] zipcode;
public char[] address;
public char[] phone;
public char[] email;
public char[] unused;
public int leverage;
public double balance;
public char[] reserved;
};
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
//
// TODO: Add code to start application here
//

DemoAccountInfo acc = new DemoAccountInfo();
acc.name = "John Smith".ToCharArray();
acc.email = "jo**@smith.com".ToCharArray();
acc.address = "some address".ToCharArray();
acc.city = "Toronto".ToCharArray();
acc.country = "Canada".ToCharArray();
acc.state = "Ontario".ToCharArray();
acc.phone = "777777777".ToCharArray();
acc.zipcode = "123456".ToCharArray();
acc.group = "demo".ToCharArray();
acc.balance = 100;
acc.leverage = 10;
OpenDemoAccount(out acc);

Console.WriteLine(acc.name);
Console.WriteLine(acc.login);
Console.WriteLine(acc.password);
Console.WriteLine("Finished.");

Console.ReadLine();

}
}
}

I think it may have something to do with the fact that I'm passing the
DemoAccountInfo parameter as a pointer in the .dll file and I'm
declaring it incorectly in c#. I may also have to implement somekind
of marshaling as well, but I'm just not sure. Keep in mind that the
code in the .dll file is programmed correctly and fallows design
specs, therefore it cannot be changed.

Nov 16 '05 #1
2 1442
On 22 Jul 2004 00:03:38 -0500, russb_69 wrote:
Russ here. I'm new to this forum. I need help in understanding why
the following code does not work. Basically, I'm defining a
structure in a c# application, and using a c++ dll to modify it.

Here's the c++ .dll file:

<snip>
struct DemoAccountInfo
{
int login;
char password[16];
char phonepassword[16];
char name[64];
char group[16];
char country[32];
char city[32];
char state[32];
char zipcode[16];
char address[32];
char phone[32];
char email[32];
char unused[72];
int leverage;
double balance;
char reserved[20];
};

<snip>

Try changing this to:
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
public struct DemoAccountInfo
{
public int login;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=16)] public string password;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=16)] public string phonepassword;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=64)] public string name;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=16)] public string group;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=32)] public string country;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=32)] public string city;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=32)] public string state;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=16)] public string zipcode;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=32)] public string address;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=32)] public string phone;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=32)] public string email;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=72)] public string unused;
public int leverage;
public double balance;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=20)] public string reserved;
};


[DllImport("DemoAccountDLLTest.dll", CharSet=CharSet.Ansi)]
public static extern void OpenDemoAccount(
out DemoAccountInfo info);

--
Tom Shelton [MVP]
Nov 16 '05 #2
just considering your "password" member for a moment, if you changed it from:
public char[] password;
to
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=16)]
public string password;
Your code will work just fine. You can change the other char[] fields to string as well.
And BTW you can also use "ref" instead of "out" and your code will work.

Hope that helps.
Abubakar.
http://joehacker.blogspot.com/
"russb_69" wrote:
Russ here. I'm new to this forum. I need help in understanding why
the following code does not work. Basically, I'm defining a
structure in a c# application, and using a c++ dll to modify it.

Here's the c++ .dll file:

// DemoAccountDLLTest.cpp : Defines the entry point for the DLL
application.
//

#include "stdafx.h"
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}

struct DemoAccountInfo
{
int login;
char password[16];
char phonepassword[16];
char name[64];
char group[16];
char country[32];
char city[32];
char state[32];
char zipcode[16];
char address[32];
char phone[32];
char email[32];
char unused[72];
int leverage;
double balance;
char reserved[20];
};

extern "C" __declspec(dllexport) void __stdcall
OpenDemoAccount(DemoAccountInfo *info)
{
info->login = 123456;
strcpy(info->password, "a1b2c3d4");
}

Here's the c# console application:

using System;
using System.Runtime.InteropServices;

namespace ConsoleApplication2
{
/// <summary>
/// Summary description for Class1.
/// </summary>
class Class1
{
[DllImport("DemoAccountDLLTest.dll")]
public static extern void OpenDemoAccount(out DemoAccountInfo
info);

[StructLayout(LayoutKind.Sequential)]
public struct DemoAccountInfo
{
public int login;
public char[] password;
public char[] phonepassword;
public char[] name;
public char[] group;
public char[] country;
public char[] city;
public char[] state;
public char[] zipcode;
public char[] address;
public char[] phone;
public char[] email;
public char[] unused;
public int leverage;
public double balance;
public char[] reserved;
};
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
//
// TODO: Add code to start application here
//

DemoAccountInfo acc = new DemoAccountInfo();
acc.name = "John Smith".ToCharArray();
acc.email = "jo**@smith.com".ToCharArray();
acc.address = "some address".ToCharArray();
acc.city = "Toronto".ToCharArray();
acc.country = "Canada".ToCharArray();
acc.state = "Ontario".ToCharArray();
acc.phone = "777777777".ToCharArray();
acc.zipcode = "123456".ToCharArray();
acc.group = "demo".ToCharArray();
acc.balance = 100;
acc.leverage = 10;
OpenDemoAccount(out acc);

Console.WriteLine(acc.name);
Console.WriteLine(acc.login);
Console.WriteLine(acc.password);
Console.WriteLine("Finished.");

Console.ReadLine();

}
}
}

I think it may have something to do with the fact that I'm passing the
DemoAccountInfo parameter as a pointer in the .dll file and I'm
declaring it incorectly in c#. I may also have to implement somekind
of marshaling as well, but I'm just not sure. Keep in mind that the
code in the .dll file is programmed correctly and fallows design
specs, therefore it cannot be changed.

Nov 16 '05 #3

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

Similar topics

2
by: Neil Fedin via .NET 247 | last post by:
I am writing a testing application that uses reflection to open assemblies and call methods. I have a function that looks like this... public void Method1 (int IDArray, bool SomethingElse){...
2
by: Martin Maat | last post by:
Hi, I am trying to create a plug-in assembly without the need to register it in the GAC. Reflection should help me out here. I got this far: private void button1_Click(object sender,...
0
by: sqcliu | last post by:
I encounter a strange problem using platform invoke using C#. The senario is this: I have a dll which uses a 3rd party static link library (lib). Inside the lib, there are some C structures...
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...
4
by: Charles Law | last post by:
Hi guys. I have two threads: a main thread and a background thread. Lots of stuff happens in the background thread that means I have to update several (lots) of controls on a form. It is...
1
by: Thai Mai Shu | last post by:
What is wrong with my call below. If I change the delegate and the CallBackComplete function to not take in parameters then the .Invoke call works fine. As soon as I put the parameters back I...
3
by: SatCom | last post by:
Hello, I had originally posted this in the winforms.controls discussion, forgive the double post, Here is where I need help... I have been porting some VB6 to VB2005 and here is the issue with...
1
by: John Kotuby | last post by:
Hi all, I am working on porting an application from VB6 to VB.NET 2003 and am running into some problems. When declaring and populating the parameters for a SQL Stored Procedure by using the...
8
by: =?Utf-8?B?UmljaA==?= | last post by:
My from contains a "Move Next" button. When the user clicks on the "Move Next" button - several procedures get invoked and eventually, the dataset underlying the form will display main data from...
1
by: =?Utf-8?B?UmFq?= | last post by:
I want to understand why C++ interop has better performance than P/Invoke. Can someone explain in detail. Thanks
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: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
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
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
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...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

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.