Passing char from C to C# using dll

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Amera
    New Member
    • Dec 2009
    • 29

    Passing char from C to C# using dll

    hello ,

    I have written these codes :

    Mydll file :

    Mydll.h

    Code:
    #ifndef MYDLL_H
    #define MYDLL_H
    
    #define EXPORT __declspec(dllexport)
    
    extern "C" void EXPORT __stdcall set(char c);
    extern "C" char EXPORT __stdcall get(void);
    
    #end

    Mydll.cpp

    Code:
    #include "MyDll.h"
    #include <windows.h>
    
    extern "C" static char o ;
    
    void __stdcall set(char c)
    { o = c; }
    
    char __stdcall get(void)
    { return o; }
    
    BOOL WINAPI DllMain(HANDLE hModule,DWORD dwReason,LPVOID lpReserved)
    { return TRUE; }
    exports.def

    Code:
    LIBRARY	"MyDll"
    EXPORTS
            set @1
            get @2
    My C# code :

    Code:
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Runtime.InteropServices;
    
    namespace Csharp
    {
        class Program
        {
            [DllImport("Mydll.dll")]
            [return: MarshalAs(UnmanagedType.I1)]
            public static extern char get();
    
            [DllImport("Mydll.dll")]
            public static extern void set([MarshalAs(UnmanagedType.I1)]char value);
    
            static void Main(string[] args)
            {
    
                Console.WriteLine(get());
                Console.Read();
    
            }
        }
    }
    My C code :

    Code:
    #include<stdio.h>
    #include<windows.h>
    main(){
    HANDLE ldll;
    typedef void (__stdcall *set)(char f);
    typedef char (__stdcall *get)(void);
    char k = 's' ;
    set Set;
    get Get;
    ldll = LoadLibrary(TEXT("MyDll.dll"));
    Set = (set)GetProcAddress(ldll, "set");
    Get = (get)GetProcAddress(ldll, "get");
    Set(k);
    
    printf("%c",Get());
    
    
    
    }

    i get no errors but i get no result also !!!

    when i call set and get in C program only i can see the char .
    the same when i call them in C#.

    but when i call set in C and get in C# so i can pass the char i get no output !!

    i can't see the char !!
  • Banfa
    Recognized Expert Expert
    • Feb 2006
    • 9067

    #2
    That is because that wont work. DLLs do not share memory between programs, each program that uses a DLL has a separate instance of the memory used by the DLL in its own address space. It has to work like this in order to allow a misbehaving program to be terminated by the OS and for the OS to be able to release all its resources and has been like this since the switch from WIN16 to WIN32 (in WIN16 a DLL actual got its own address space and the data in a DLL was shared between all programs that used it).

    If you want to pass a char or any data from a C program to a C# program you will need to find an alternate method. I guess that pipes might work.

    Comment

    • Amera
      New Member
      • Dec 2009
      • 29

      #3
      i can use C++ manage class right ?

      i did it in the dll

      but i couldn't call it from C#

      the class exported from dll can't be known in C# !!!

      i get the error :

      The type or namespace name 'Adder' could not be found (are you missing a using directive or an assembly reference?)

      this is my dll code after i added the exported class :

      Mydll.h :

      Code:
      #undef AFX_DATA
      #define AFX_DATA AFX_EXT_DATA
      
      #ifndef MYDLL_H
      #define MYDLL_H
      
      #define EXPORT __declspec(dllexport)
      
      extern "C" void EXPORT __stdcall set(char c);
      
      class __declspec(dllexport) Adder
      {
      	public:
      		Adder(){;};
      		~Adder(){;};
      		char get(void);
      };
      
      #endif
      
      
      #undef AFX_DATA
      #define AFX_DATA

      Mydll.cpp :

      Code:
      #include "MyDll.h"
      #include <windows.h>
      
      #using <mscorlib.dll>
      using namespace System;
      using namespace System::Collections;
      
      extern "C" static char o ;
      
      #pragma unmanaged directive
      char Adder::get(void)
      {
      	return o;
      }
      
      
      #pragma unmanaged directive
      void __stdcall set(char c)
      { o = c; }
      
      
      #pragma unmanaged directive
      BOOL WINAPI DllMain(HANDLE hModule,DWORD dwReason,LPVOID lpReserved)
      { return TRUE; }
      and this is C# where i called the class above :

      Code:
      using System;
      using System.Collections.Generic;
      using System.Text;
      using System.Runtime.InteropServices;
      
      namespace Csharp
      {
          class Program
          {
              [DllImport("Mydll.dll")]
              [return: MarshalAs(UnmanagedType.I1)]
              public static extern char get();
      
              [DllImport("Mydll.dll")]
              public static extern void set([MarshalAs(UnmanagedType.I1)]char value);
      
              static void Main(string[] args)
              {
                  Adder a = new Adder();
                  Console.WriteLine(a.get());
                  Console.WriteLine();
                  Console.Read();
      
              }
          }
      }

      Comment

      • Banfa
        Recognized Expert Expert
        • Feb 2006
        • 9067

        #4
        I am not that familiar with .NET/CLR programming. However the separation of processes virtual memory maps is a feature provided by the OS and should not as such be affected by the language you choose to implement your programs in.

        That is the is no special magic bullet language that allows 2 different processes to suddenly be able to share memory. The .NET framework may well provide ways round this, in fact the WIN32 API provides ways round this such as memory mapped files.

        It is not possible to transfer values between programs via a shared library on Windows. .NET may provide a way round this but I am not familiar enough with .NET to know but it would be a .NET implemented thing not something implemented natively.

        Comment

        • weaknessforcats
          Recognized Expert Expert
          • Mar 2007
          • 9214

          #5
          The class Adder is a C++ class. It has been compiled as C++ and is not accessible from C#.

          You will need towrite a C++ function you can call from C#. The C++ function will do the work in C++ and pass the result (if necessary) back to C#.

          This should akll be explained in the MSDN Interoperabilit y topics between C# and C++.

          Comment

          Working...