question

MarkusFreitag-0088 avatar image
0 Votes"
MarkusFreitag-0088 asked RLWA32-6355 commented

What are my options? Calls from C++ C# DLL functions, how?


Hello,

I have a C# DLL. I need to call these functions from C++ unmanaged application which is statically bound, no CLI is possible.

What are my options?
Maybe I don't need a CLI wrapper class. Maybe it is easier. Can you make sample for all three functions, please? Thanks in advance!


   using System;
     using System.Collections.Generic;
     using System.Text;
     using System.Windows.Forms;
     using System.IO;
        
     namespace ManagedCSharp
     {
         public static class ManagedClass
         {
             static List<string> ListSerials;
             static Dictionary<int, string> DicPosSerial;
        
             public static void ShowValue(ref int value)
             {
                 DialogResult result = MessageBox.Show("C# Message Box", "C# Message Box", MessageBoxButtons.OKCancel);
                 if (result == DialogResult.OK)
                 {
                     value = 1;
                     ListSerials = new List<string>();
                     DicPosSerial = new Dictionary<int, string>();
                 }
                 else
                     value = 2;
                 return;
             }
        
             public static string GetOrder(string input)
             {
                 return "[ORDER_RES]|2424245|0793|1000|2421Ad";
             }
        
             public static bool SendResult(int pos, string serial)
             {
                 ListSerials.Add(serial);
        
                 DicPosSerial.Add(pos, serial);
        
                 return true;
             }
         }
     }


113542-cpp-exe-mfc-common-dll.png


dotnet-csharpc++dotnet-cli
· 4
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

One option that you may want to consider is to use COM. A managed in-process COM server written in C# can interoperate with an unmanaged C++ COM client. The C++ client can instantiate the managed COM object, call its methods, get/set its properties and sink events fired by the server. No C++/CLI wrappers would be needed.

1 Vote 1 ·

That looks complicated. Can't it be simpler and do you have a concrete example available? Thanks in advance.

Perhaps via CLI after all. But how and where do I integrate the DLL into the C++ application? Or is it only possible via DLL import and I only have to specify the path? Do you have an example here?
I googled but there is no short striking example of how to do it. Is so difficult for me in this case.


0 Votes 0 ·
RLWA32-6355 avatar image RLWA32-6355 MarkusFreitag-0088 ·

Its old but I have shared a C# COM Server sample for you on OneDrive at https://1drv.ms/u/s!AmnqrCFBv4nDgX6F7i4pxFQfzHBm?e=NOyJOs
Another possibility is to use delegates and function pointers. An example of calling back into C# from a C++ dll is at https://1drv.ms/u/s!AmnqrCFBv4nDggCbJ7WXNnfm4lzG?e=HTI2tH
Also, take a look at Calling-Csharp-NET-methods-from-unmanaged-C-Cplusp


1 Vote 1 ·
Show more comments
RLWA32-6355 avatar image
2 Votes"
RLWA32-6355 answered RLWA32-6355 commented

@MarkusFreitag-0088 I put together a small sample using VS2019 that illustrates using a C++/CLI DLL to interoperate with a C# class library from unmanaged C++. It consists of a solution with 3 projects (C# class library, C++/CLI DLL and C++ console application). You can get it from https://1drv.ms/u/s!AmnqrCFBv4nDggHoFw90fA7As4eK?e=pXnIqv


· 72
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

You are the best! Thanks a lot.

It looks good for the first one. I'll check it more exactly.


  int wmain()
     {
         int i = 0;
         CString strOrder(L"This is a test");
        
         wprintf_s(L"Before value of i is %d\n", i);
         Call_ShowValue(i);
         wprintf_s(L"After value of i is %d\n", i);
        
         CString s = Call_GetOrder(strOrder);
         wprintf_s(L"GetOrder returned %s\n", (LPCWSTR)s);

Then I can use all data types double, int string. Right?



   namespace CSharpLibrary
         {
             public static class ManagedCSharp
             {
                 static List<string> ListSerials;
                 static Dictionary<int, string> DicPosSerial;


I can now insert a list or a dictionary into this class and fill it.
That must be possible, because of the instantiation I'm not sure if I have
to consider something. What is your opinion?



Background:
I have an old C++ application, this has functions. Depending on the state I have to do something.
The idea is to do it with C#, since I have it easier there.
I need to implement a HttpWeb interface. The main problem.

0 Votes 0 ·

I'm taking a closer look.
I have made a new VS2017 project. So did you. I cannot compile it.

Have you made any special settings?


the function cannot be added by the new declaration.
A as DLL Import must not be defined.
Does this not work under VS2017?




0 Votes 0 ·
SimpleSamples avatar image SimpleSamples MarkusFreitag-0088 ·

I am using VS 2017 too and I am unable to open the solution too.

1 Vote 1 ·

@SimpleSamples I downloaded the shared VS2019 solution/projects from Onedrive to a VM that has VS2017 installed. After unblocking the zip file I extracted the solution/projects from the zip file. For VS2017 it was necessary to retarget the Windows SDK version and also set the build tools for the CliLib and CppClient projects to v141. After that, everything built without any problem in my test.

1 Vote 1 ·
Show more comments
SimpleSamples avatar image SimpleSamples MarkusFreitag-0088 ·

I was able to create a new solution and create relevant projects in the solution and copy the code into the new projects. It works for me that way.

1 Vote 1 ·
RLWA32-6355 avatar image RLWA32-6355 MarkusFreitag-0088 ·

According to Microsoft you should be able to open and work with VS2019 solutions/projects in VS2017. However, if you have created your own solution and projects then they are likely missing some settings that are needed.

For example, the problem with the __declspec(dllimport) being used in the CliLib project is because you have not added the CLILIB_EXPORTS macro to the C++ prepocessor definitions for all platforms/configurations. For example, the shared project settings for Win32/Debug looks like this in the files shared on OneDrive -
113635-preproc.png

And there are some settings in the CppClient project that your project is probably missing -
Additional library dependency -
113602-cppinput.png
and also Additional library directory-
113603-cppgeneral.png


0 Votes 0 ·
preproc.png (26.3 KiB)
cppinput.png (26.1 KiB)
cppgeneral.png (31.7 KiB)

For example, the problem with the __declspec(dllimport) being used in the CliLib project is because you have not added the CLILIB_EXPORTS macro to the C++ prepocessor definitions for all platforms/configurations. For example, the shared project settings for Win32/Debug looks like this in the files shared on OneDrive -

Thanks for the quick response.

I will check it. When we need dllimport?

 #ifdef CLILIB_EXPORTS
 #define CLILIB_API __declspec(dllexport)
 #else
 #define CLILIB_API __declspec(dllimport)
 #endif

Sorry it is not working unde VS2017

113604--1a.png



Can you upload it for VS2017?

0 Votes 0 ·
-1a.png (33.7 KiB)
Show more comments
SimpleSamples avatar image
1 Vote"
SimpleSamples answered MarkusFreitag-0088 edited

In your first version of this question at C# to C++/MFC duplex mode - Concept I did not understand that the reason you think you cannot modify the MFC application is the static linking. See Managed C++ Wrapper For Unmanaged Code. Believe it or not, you can use C++/CLI in a C++ program that is statically linked. I wrote the original article from code I wrote to call Microsoft Detours, which is (was) only available as a static library. You can add C++/CLI to an existing C++ application such as a MFC application.


· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Hello @SimpleSamples ,


        public static void ShowValue(ref int value)     
        public static string GetOrder(string input)      
        public static bool SendResult(int pos, string serial)


You can add C++/CLI to an existing C++ application such as a MFC application

I think is difficult, can you show how you would do it with my three functions? Thanks in advance.


0 Votes 0 ·
rupeshshukla-4529 avatar image
1 Vote"
rupeshshukla-4529 answered MarkusFreitag-0088 commented

You can get a small sample from

call c# dll or class within c++ project



Thanks

· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Thanks for the link!

1 Vote 1 ·