CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 8 of 8
  1. #1
    Join Date
    Jun 2003
    Posts
    258

    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();
    
    		}
    	}
    }

  2. #2
    Join Date
    Jan 2002
    Location
    Scaro, UK
    Posts
    5,940
    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.
    www.pinvoker.com - PInvoker - the .NET PInvoke Interface Exporter for C++ Dlls.

  3. #3
    Join Date
    Jun 2003
    Posts
    258
    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

  4. #4
    Join Date
    May 2000
    Location
    KY, USA
    Posts
    18,652
    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.

  5. #5
    Join Date
    Jan 2002
    Location
    Scaro, UK
    Posts
    5,940
    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.
    www.pinvoker.com - PInvoker - the .NET PInvoke Interface Exporter for C++ Dlls.

  6. #6
    Join Date
    Apr 2003
    Posts
    108

    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.

  7. #7
    Join Date
    Aug 2003
    Location
    London
    Posts
    515

    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"!

  8. #8
    Join Date
    Apr 2003
    Posts
    108

    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
  •  





Click Here to Expand Forum to Full Width

Featured