Results 1 to 16 of 16

Thread: [RESOLVED] loading C dlls in C#

  1. #1

    Thread Starter
    Member nci's Avatar
    Join Date
    Aug 2003
    Posts
    43

    Resolved [RESOLVED] loading C dlls in C#

    hello,
    i'm working on a way to load a dll i made in C into C#. I made a simple function that returns a string "hello" and C# calls this function and gets the string just fine. I then tried to pass a structure to C#, but this causes errors.

    my C code structure
    Code:
    typedef struct _MY_STRUCT
    {
    int  sName;
    int  sPhone;
    }MY_STRUCT, *LPMY_STRUCT;
    my C# structure
    Code:
            public struct MY_STRUCT
            {
                public int sName;
                public int sPhone;
            }

    whenever I call
    Code:
                
    MY_STRUCT MyStruct = new MY_STRUCT();
    
    //MessageBox.Show(Marshal.SizeOf(MyStruct).ToString());
    
    //compiler doesnt like this line...
    Marshal.PtrToStructure(GetString(), MyStruct);
                
    MessageBox.Show(MyStruct.sName.ToString());
    MessageBox.Show(MyStruct.sPhone.ToString());
    I get a runtime error: "The structure must not be a value class.
    Parameter name: structure"

    I've also just tried doing this:
    Code:
    MyStruct = GetString(); //GetString is just the name of the function
    but all i get is a runtime error saying type signiture is not compatible
    by using sizeof, I know that both the C structure and the C# structure are 8 bytes long, but I dont know what else to do (and ive tried everything I could think of)

    Please, could someone help me?

  2. #2
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: loading C dlls in C#

    I'm not sure why a method named "GetString" would return a structure with two int fields but, that aside, can we see the C definition of the function and also the C# declaration?
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  3. #3

    Thread Starter
    Member nci's Avatar
    Join Date
    Aug 2003
    Posts
    43

    Re: loading C dlls in C#

    ok, i tried it with integers and still no luck, here is the code:

    Code:
    typedef struct _MY_STRUCT
    {
    int  iName;
    int  iPhone;
    }MY_STRUCT, *LPMY_STRUCT;
    
    
    C_EXPORT LPMY_STRUCT __cdecl GetInterface (void)
    {
      static  struct _MY_STRUCT  XMPTagInterface;
      memset(&XMPTagInterface,0,sizeof(XMPTagInterface));
      
      XMPTagInterface.iName=1234;
      XMPTagInterface.iPhone=5678;
      
      return  &XMPTagInterface;
    }
    thats how it is in the dll



    in C#
    Code:
    public struct MY_STRUCT
    {
    public int iName;
    public int iPhone:
    }        
    
    [DllImport("tag_interface.dll")]
    public static extern IntPtr GetInterface();
                                 |--------------------i dunno if this is the right type      
                                                              I also tried MY_STRUCT
    
    
    //in some private meothod
    MY_STRUCT MyStruct = new MY_STRUCT();
    
    //compiler hates this line-----------------|
    Marshal.PtrToStructure(GetInterface(), MyStruct);
    says it cant be a value type structure I don;t event know what that means...lol
    this code works fine when i load my test dll in my C app, but C# chokes on it
    I dunno what to do. and sorry for the sadly written example

  4. #4
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: loading C dlls in C#

    There are two overloads of PtrToStructure. The one you are using cannot be used with value types, as the error message says. That means that the second parameter must be an instance of a class or other reference type, NOT a structure. If you want to marshal to a value type then you must use the other overload. In that case you specify the type and the method returns a boxed instance, which you must unbox by casting:
    CSharp Code:
    1. MyStruct s = (MyStruct)Marshal.PtrToStructure(GetInterface(), typeof(MyStruct));
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  5. #5

    Thread Starter
    Member nci's Avatar
    Join Date
    Aug 2003
    Posts
    43

    Re: loading C dlls in C#

    oh...
    thanks!

  6. #6
    type Woss is new Grumpy; wossname's Avatar
    Join Date
    Aug 2002
    Location
    #!/bin/bash
    Posts
    5,682

    Re: [RESOLVED] loading C dlls in C#

    This would be easier to do with unsafe code but since you've got a working solution I won't bother going into detail unless you want me to.
    I don't live here any more.

  7. #7

    Thread Starter
    Member nci's Avatar
    Join Date
    Aug 2003
    Posts
    43

    Re: [RESOLVED] loading C dlls in C#

    yeah, i was trying to do it without unsafe code. but the whole reason i'm doing this in the first place, is becuase writing a plugin system in C# is a nightmare. So, i'm doing my plugins in C and my main app in C# (at least until I master C# dlls )

  8. #8
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: [RESOLVED] loading C dlls in C#

    Quote Originally Posted by nci
    writing a plugin system in C# is a nightmare.
    Since when? I've never done it myself but I've read about it and it seems pretty simple to me. What exactly is so nightmarish about it?
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  9. #9

    Thread Starter
    Member nci's Avatar
    Join Date
    Aug 2003
    Posts
    43

    Re: [RESOLVED] loading C dlls in C#

    well, i viewed a few exaples and tutorials for it, but I'm soo lost. I just dont know enough about inheritence and interfaces yet. It just looks sooo complicated. eventually i'll understand it, but right now, its easier for me to manage plugins in C code

  10. #10
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: [RESOLVED] loading C dlls in C#

    It's actually not very complicated at all, but if you want to stick to C plugins for the moment then fair enough.

    As for interfaces, they're pretty much like a C header file, with a list of methods but no implementation for any of them. Classes can then implement that interface by providing an implementation for each of the members it defines. You can then have various disparate types all able to be acst as the same type and therefore used in the same way.

    For a real-life example, consider your computer and how many varied peripherals are attached to it, or could be attached to it. It's likely that many of those peripherals would have a USB interface. It doesn't matter what the peripherals do or how they do it, as long as they implement the USB interface your computer can talk to them.

    Your app would be the same. You define the interface a plugin must implement. You can then load any and all plugins no matter what they do or how they do it. All your app cares about is that they implement your interface. The interface is just a bunch or method and property signatures. How each method and property is implemented is completely up to the discretion of the plugin author.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  11. #11
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: [RESOLVED] loading C dlls in C#

    Here's a quick code example:
    csharp Code:
    1. public partial class Form1 : Form
    2. {
    3.     public Form1()
    4.     {
    5.         InitializeComponent();
    6.     }
    7.  
    8.     private void Form1_Load(object sender, EventArgs e)
    9.     {
    10.         Plugin1 p1 = new Plugin1();
    11.         Plugin2 p2 = new Plugin2();
    12.  
    13.         this.AboutPlugin(p1);
    14.         this.AboutPlugin(p2);
    15.     }
    16.  
    17.     private void AboutPlugin(IPlugin plugin)
    18.     {
    19.         plugin.About();
    20.     }
    21. }
    22.  
    23.  
    24. public interface IPlugin
    25. {
    26.     void About();
    27. }
    28.  
    29.  
    30. public class Plugin1 : IPlugin
    31. {
    32.     #region IPlugin Members
    33.  
    34.     void IPlugin.About()
    35.     {
    36.         MessageBox.Show("All about Plugin1");
    37.     }
    38.  
    39.     #endregion
    40. }
    41.  
    42.  
    43. public class Plugin2 : IPlugin
    44. {
    45.     #region IPlugin Members
    46.  
    47.     void IPlugin.About()
    48.     {
    49.         MessageBox.Show("All about Plugin2");
    50.     }
    51.  
    52.     #endregion
    53. }
    Note that the IPlugin interface declares a method named About that takes no parameters and returns no value. It provides no implementation, leaving that up to the classes that will implement the interface. The Plugin1 and Plugin2 classes both implement the IPlugin interface, and therefore implement the IPlugin.About method. Each class implements the method as it sees fit.

    Withing the application the objects are treated as IPlugin objects, not there actual type. Because the IPlugin type has an About method we know we can call that method on any and all plugins.

    In a real situation each of the plugin classes would be declared in its own DLL and you would load those DLLs at run time and access the class using reflection. That adds some complexity but it's still just a few lines of code to do that.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  12. #12
    Interweb adm/o/distrator Paul M's Avatar
    Join Date
    Nov 2006
    Location
    Australia, Melbourne
    Posts
    2,306

    Re: [RESOLVED] loading C dlls in C#

    You could also abstract it a little and create a new instance by doing it like so...

    Code:
    IPlugin plgIn = new Plugin1();

  13. #13
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: [RESOLVED] loading C dlls in C#

    Quote Originally Posted by Hell-Lord
    You could also abstract it a little and create a new instance by doing it like so...

    Code:
    IPlugin plgIn = new Plugin1();
    In a real situation you couldn't because you won't have compile-time references to the DLLs containing the plugins, so you won't know the Plugin1 type. You have to load the DLLs at run time and interrogate them using reflection.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  14. #14
    Interweb adm/o/distrator Paul M's Avatar
    Join Date
    Nov 2006
    Location
    Australia, Melbourne
    Posts
    2,306

    Re: [RESOLVED] loading C dlls in C#

    Inside the DLL can't you do...

    Code:
    [assmebly: Plugin(typeof(myplugin))]

  15. #15

    Thread Starter
    Member nci's Avatar
    Join Date
    Aug 2003
    Posts
    43

    Re: [RESOLVED] loading C dlls in C#

    that was the first real example that made sense. See, normally for my C programs, i create a type structure that has all of the plugin details, like name, author, description, and a bunch of function pointers that are required (pretty much the interface) then I just pass the structure off to the app, and the app would call the plugin functions like

    Code:
    MyPlugin[2]->DoMath(2, 4); //what it does with 2 and 4 is up to the plugin
    i like your example, jmcilhinney, it makes it look really simple. I've looked at all kinds of tutorials and my head was spinning. So, i may give this a shot.
    All of the examples i've seen had an interface dll and also plugin dlls. Is this the way it has to be? or can an app just look at a directory and load all of the dlls in it?

    currently, my C# app uses a dll that controls the other plugins, simply becuase I do not quiet no how to load dlls at runtime. I suppose i could import a LoadLibrary api, but, I didnt think of that till just now

    anyway, i'm still learning C# and it is quickly becoming my favorite language.

  16. #16
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: [RESOLVED] loading C dlls in C#

    The general idea would be that you would have a folder dedicated to plugins, into which each author would install their DLL. An alternative could be that you have a registry key dedicated to storing the locations of plugin libraries, where each athor would add the path to their library and you'd read it from there.

    You should take a look at the Assembly class, which is used to load assemblies at run time. I've never actually done this stuff myself so I don't know all the details, but basically you load the assembly and then interrogate it to find types that implement your plugin interface. The interrogation is done using reflection, which you can read about in the documentation for the System.Reflection namespace and the System.Type class.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

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