|
-
June 27th, 2004, 11:19 AM
#1
pointer to struct passing
Hi everyone, I have a hopefully simple problem. I've written a dll in C++ (unmanaged, UNICODE). The dll takes care of all of the threading and the memory management. The format of my C++ struct is:
Code:
struct OSDParam{
wchar_t* userfont;
int fontsize;
int Monitor;
int Displength;
int alpha;
wchar_t* text;
int Coloring[3];
float x;
float y;
int fontstyle;
HANDLE procHand;
OSDParam()
{
userfont = L"Times New Roman";
fontsize = 45;
Monitor = 2;
Displength = 5;
alpha = 255;
text = L"No text set for OSD";
Coloring[0]= 0;
Coloring[1] = 0;
Coloring[2] = 0;
x = 0.0;
y = 0.0;
fontstyle = 0;
HANDLE procHand = NULL;
}
};
I have a CreateParam function that takes a NULL pointer from a client program and supplies it with an address and default values. In C++ code (which works) it looks like
Code:
OSDParam* params = NULL;
CreateParam(params);
This works very well. Now, I'm trying to create a client program in C# and I can't seem to provide an address for the struct. It runs, but the values passed to the client are incorrect and frequently ridiculous. This would seem to imply that I'm just randomly accessing memory and not assigning it like one does in C++. The test code follows below. If anyone has any ideas how I can assign the address through the CreateParam function, please let me know.
~Steve
Code:
using System;
using System.Runtime.InteropServices;
using System.Text;
namespace ConsoleApplication1
{
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct OSDParam
{
public String userfont;
public int fontsize;
public int Monitor;
public int Displength;
public int alpha;
public String text;
public int[] Coloring;
public float x;
public float y;
public int fontstyle;
}
/// <summary>
/// Summary description for Class1.
/// </summary>
///
public class OSDdll
{
[DllImport("OSD.dll")]
public static extern int InitOSD();
[DllImport("OSD.dll")]
public static extern int ExitOSD();
[DllImport("OSD.dll")]
public static extern int CreateParam(ref OSDParam Parameters);
[DllImport("OSD.dll")]
public static extern int SemiPermText(OSDParam Parameters);
}
class Class1
{
[STAThread]
static void Main(string[] args)
{
OSDParam t = new OSDParam();
OSDdll.InitOSD();
//Pass the address to the struct that my dll manages
OSDdll.CreateParam(ref t);
Console.WriteLine(t.fontsize);
OSDdll.ExitOSD();
}
}
}
-
June 28th, 2004, 08:07 PM
#2
Oh boy, bad design abounds again :
What on earth do you think you are doing ?
Is this object oriented ?
I think not.
Are you a C programmer by any chance who's trying to learn object orientation ?
C programs use structs to hold data and pass them about through effectively static functions.
You really should learn object orientation.
And if you're having problems with interop, I suggest you write your own classes in C++.NET to interface between C# and your libraries in a nice and object oriented way.
I personally always do this so I can control the interop (i.e. the interoperability so that native interfaces with .NET in an expected way and vice-versa).
Darwen.
Last edited by darwen; June 28th, 2004 at 08:09 PM.
-
June 28th, 2004, 10:45 PM
#3
Hi Darwen,
I am learning OO, but I didn't see the need for a class here as all I wanted to do was get some information into my dll. This seemed to make more sense than passing a huge list of parameters (which was how I did it at first). I'm passing pointers to the structs as I'm going to be using a mixed threading environment and I wanted to control all memory allocation/threading from the dll. If you could give any pointers, no pun intended, I would appreciated it. Why would I need a class for this? Also, I was under the impression that a class was a struct where all of the members are private by default instead of public. My program is fairly simple, so I didn't see the need for complicated objects, and a struct seemed reasonable, although I've only been programming for about a year...
I still don't see why I can't assign an address of a filled struct however.
~Steve
-
June 29th, 2004, 02:05 AM
#4
Originally posted by darwen
Oh boy, bad design abounds again :
What on earth do you think you are doing ?
Is this object oriented ?
I think not.
Are you a C programmer by any chance who's trying to learn object orientation ?
C programs use structs to hold data and pass them about through effectively static functions.
You really should learn object orientation.
Well...you have not be born and your first word was object-orientation, thus, I do not think that the above wording is appropriate.
Furthermore, structures does not indicate that there is no object-orientation. Structures are still widely used in object-oriented environments nowadays.
-
June 29th, 2004, 05:04 AM
#5
Fair enough - I'm sorry. I read the struct as all of it being member variables which would have made it massive.
Another bad day for darwen I suppose...
But my additional point still stands true : you can write a .NET wrapper assembly around the functions which use this struct and then convert it to a __gc struct for passing into C#.
Darwen.
-
January 3rd, 2007, 05:00 AM
#6
Re: pointer to struct passing
Hello diehardii,
I am a c++ programmer who is trying to move on c#, without having to return to school. And I have exactely the same problem than you.
Could you please tell me if you finally solved this problem ?
And if yes, could you please explain how ?
Thank you.
-
January 3rd, 2007, 05:54 AM
#7
Re: pointer to struct passing
Don't you need to use the Interop.Marshal functions to allocate unmanaged memory to your C# client. Eg
(This code is lifted from an article I found that allows me to use the 'Select Users or Groups' dialog from within my c# apps)
Code:
/// <summary>
/// The DSOP_SCOPE_INIT_INFO structure describes one or more scope types that have the same attributes. A scope type is a type of location, for example a domain, computer, or Global Catalog, from which the user can select objects.
/// A scope type is a type of location, for example a domain, computer, or Global Catalog, from which the user can select objects.
/// </summary>
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto), Serializable]
public struct DSOP_SCOPE_INIT_INFO
{
public uint cbSize;
public uint flType;
public uint flScope;
[MarshalAs(UnmanagedType.Struct)]
public DSOP_FILTER_FLAGS FilterFlags;
[MarshalAs(UnmanagedType.LPWStr)]
public string pwzDcName;
[MarshalAs(UnmanagedType.LPWStr)]
public string pwzADsPath;
public uint hr;
}
DSOP_SCOPE_INIT_INFO[] scopeInitInfo = new DSOP_SCOPE_INIT_INFO[2];
// Initialize 1st search scope
scopeInitInfo[0].cbSize = (uint)Marshal.SizeOf(typeof(DSOP_SCOPE_INIT_INFO));
scopeInitInfo[0].flType = DSOP_SCOPE_TYPE_FLAGS.DSOP_SCOPE_TYPE_GLOBAL_CATALOG; //Convert.ToUInt32("3FE",16);
scopeInitInfo[0].flScope = DSOP_SCOPE_INIT_INFO_FLAGS.DSOP_SCOPE_FLAG_DEFAULT_FILTER_COMPUTERS + 1; // Starting !?
scopeInitInfo[0].FilterFlags.Uplevel.flBothModes = DSOP_FILTER_FLAGS_FLAGS.DSOP_FILTER_COMPUTERS + 1; // +1 = advanced view, Check MSDN for the available options
scopeInitInfo[0].FilterFlags.flDownlevel = DSOP_DOWNLEVEL_FLAGS.DSOP_DOWNLEVEL_FILTER_COMPUTERS;
scopeInitInfo[0].pwzADsPath = null;
scopeInitInfo[0].pwzDcName = null;
scopeInitInfo[0].hr = 0;
// Allocate memory from the unmananged mem of the process, this should be freed later
IntPtr refScopeInitInfo = Marshal.AllocHGlobal(Marshal.SizeOf (typeof (DSOP_SCOPE_INIT_INFO)) * 2);
// Marshal structs to pointers
Marshal.StructureToPtr (scopeInitInfo[0], refScopeInitInfo,true);
If it helped, then please rate the post by clicking "Rate this post"!
-
January 3rd, 2007, 08:22 AM
#8
Re: pointer to struct passing
Thank you for your help. Yes I am convinced that I have to use the Interop.Marshal functions. I already tried similar code during several hours, without success.
I am looking hopelessly for somebody who did it !
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|