By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,771 Members | 1,709 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,771 IT Pros & Developers. It's quick & easy.

Passing char from C to C# using dll

P: 29
hello ,

I have written these codes :

Mydll file :

Mydll.h

Expand|Select|Wrap|Line Numbers
  1. #ifndef MYDLL_H
  2. #define MYDLL_H
  3.  
  4. #define EXPORT __declspec(dllexport)
  5.  
  6. extern "C" void EXPORT __stdcall set(char c);
  7. extern "C" char EXPORT __stdcall get(void);
  8.  
  9. #end
  10.  

Mydll.cpp

Expand|Select|Wrap|Line Numbers
  1. #include "MyDll.h"
  2. #include <windows.h>
  3.  
  4. extern "C" static char o ;
  5.  
  6. void __stdcall set(char c)
  7. { o = c; }
  8.  
  9. char __stdcall get(void)
  10. { return o; }
  11.  
  12. BOOL WINAPI DllMain(HANDLE hModule,DWORD dwReason,LPVOID lpReserved)
  13. { return TRUE; }
  14.  
exports.def

Expand|Select|Wrap|Line Numbers
  1. LIBRARY    "MyDll"
  2. EXPORTS
  3.         set @1
  4.         get @2
  5.  
My C# code :

Expand|Select|Wrap|Line Numbers
  1.  
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Text;
  5. using System.Runtime.InteropServices;
  6.  
  7. namespace Csharp
  8. {
  9.     class Program
  10.     {
  11.         [DllImport("Mydll.dll")]
  12.         [return: MarshalAs(UnmanagedType.I1)]
  13.         public static extern char get();
  14.  
  15.         [DllImport("Mydll.dll")]
  16.         public static extern void set([MarshalAs(UnmanagedType.I1)]char value);
  17.  
  18.         static void Main(string[] args)
  19.         {
  20.  
  21.             Console.WriteLine(get());
  22.             Console.Read();
  23.  
  24.         }
  25.     }
  26. }
  27.  
  28.  
My C code :

Expand|Select|Wrap|Line Numbers
  1. #include<stdio.h>
  2. #include<windows.h>
  3. main(){
  4. HANDLE ldll;
  5. typedef void (__stdcall *set)(char f);
  6. typedef char (__stdcall *get)(void);
  7. char k = 's' ;
  8. set Set;
  9. get Get;
  10. ldll = LoadLibrary(TEXT("MyDll.dll"));
  11. Set = (set)GetProcAddress(ldll, "set");
  12. Get = (get)GetProcAddress(ldll, "get");
  13. Set(k);
  14.  
  15. printf("%c",Get());
  16.  
  17.  
  18.  
  19. }
  20.  
  21.  

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 !!
Jan 3 '10 #1

✓ answered by weaknessforcats

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 Interoperability topics between C# and C++.

Share this Question
Share on Google+
4 Replies


Banfa
Expert Mod 5K+
P: 8,916
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.
Jan 3 '10 #2

P: 29
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 :

Expand|Select|Wrap|Line Numbers
  1.  
  2. #undef AFX_DATA
  3. #define AFX_DATA AFX_EXT_DATA
  4.  
  5. #ifndef MYDLL_H
  6. #define MYDLL_H
  7.  
  8. #define EXPORT __declspec(dllexport)
  9.  
  10. extern "C" void EXPORT __stdcall set(char c);
  11.  
  12. class __declspec(dllexport) Adder
  13. {
  14.     public:
  15.         Adder(){;};
  16.         ~Adder(){;};
  17.         char get(void);
  18. };
  19.  
  20. #endif
  21.  
  22.  
  23. #undef AFX_DATA
  24. #define AFX_DATA
  25.  
  26.  

Mydll.cpp :

Expand|Select|Wrap|Line Numbers
  1.  
  2. #include "MyDll.h"
  3. #include <windows.h>
  4.  
  5. #using <mscorlib.dll>
  6. using namespace System;
  7. using namespace System::Collections;
  8.  
  9. extern "C" static char o ;
  10.  
  11. #pragma unmanaged directive
  12. char Adder::get(void)
  13. {
  14.     return o;
  15. }
  16.  
  17.  
  18. #pragma unmanaged directive
  19. void __stdcall set(char c)
  20. { o = c; }
  21.  
  22.  
  23. #pragma unmanaged directive
  24. BOOL WINAPI DllMain(HANDLE hModule,DWORD dwReason,LPVOID lpReserved)
  25. { return TRUE; }
  26.  
and this is C# where i called the class above :

Expand|Select|Wrap|Line Numbers
  1.  
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Text;
  5. using System.Runtime.InteropServices;
  6.  
  7. namespace Csharp
  8. {
  9.     class Program
  10.     {
  11.         [DllImport("Mydll.dll")]
  12.         [return: MarshalAs(UnmanagedType.I1)]
  13.         public static extern char get();
  14.  
  15.         [DllImport("Mydll.dll")]
  16.         public static extern void set([MarshalAs(UnmanagedType.I1)]char value);
  17.  
  18.         static void Main(string[] args)
  19.         {
  20.             Adder a = new Adder();
  21.             Console.WriteLine(a.get());
  22.             Console.WriteLine();
  23.             Console.Read();
  24.  
  25.         }
  26.     }
  27. }
  28.  
  29.  
  30.  
  31.  
Jan 4 '10 #3

Banfa
Expert Mod 5K+
P: 8,916
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.
Jan 4 '10 #4

weaknessforcats
Expert Mod 5K+
P: 9,197
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 Interoperability topics between C# and C++.
Jan 4 '10 #5

Post your reply

Sign in to post your reply or Sign up for a free account.