• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 3198
  • Last Modified:

Calling C++ function from C#

Hi, I have a C# application that has to call one C++ function

here is the code that I want to use from C#:

[DllImport("DllTest.dll")]
public static extern string Test(string param);

[STAThread]
static void Main()
{
      string tmp =Test("test1");
      Console.Out.WriteLine(tmp);
}


Here is what I would write in DllTest if it was C#

public static extern string Test(string inParam)
{
      return inParam + " SPECIAL";
}





Can you please give me an equivalent in C++ so that function will port to C# without a problem

Thank you
0
RodionP
Asked:
RodionP
  • 4
  • 3
1 Solution
 
OctabunCommented:
The function you request looks like

      static public __gc class Class1
      {
      public:
            static String * Test(String * t) {
                  String * p = new String("Special");
                  return t->Concat(t, p);
            }
      };

please note that it uses managed extencions and should be compiled to a .NET assembly. You do not need

[DllImport("DllTest.dll")]
public static extern string Test(string param);

to access a .NET assembly containing C++ code. Just add the assembly to project references.

If you need a function in an unmanaged C++ dll to return a managed class, which can be the case since you use the DLllImport attribute, then it is impossible because the unmanaged DLL cannot access CLR and create a new instance of a managed class.
0
 
RodionPAuthor Commented:
This is C++ made by Visual Studio 6, meaning, no managed code, that is why I need to use DllImport, I need plain C++/ANSI C code
0
 
RodionPAuthor Commented:
I do not need to create an instance of unmanaged class, I need to call an external function, a static function, just some function written in unmanaged code
0
Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 
OctabunCommented:
Aha, you want the call to "just work", without thinking much about what is going on. Yes, Microsoft has the "it just works" interop approach.

In C++ DLL you create a function

================ C++ code (C, actually)

char buf [100];

char * __cdecl Test (char * p) {
      size_t n = strlen(p);
            memcpy(buf, p, n);
      char tmp [] = "SPECIAL";
      memcpy(&buf[n], tmp, 7);
      return buf;
}

================ C++ code ends

Export it with the def file

================ TestDLL.def

; TestDLL.def : Declares the module parameters for the DLL.

LIBRARY      "TestDLL"

EXPORTS
    ; Explicit exports can go here
    Test  @1

================ TestDLL.def ends

copy TestDLL.dll to the folder your C# app is compiled to, and call Test in C# as

================ Class1.cs

using System;
using System.Runtime.InteropServices;

namespace ConsoleApplication1
{
      class Class1
      {
        [DllImport("TestDLL.dll")]
        public static extern string Test(string p);

        [STAThread]
            static void Main(string[] args)
            {
            Console.Out.WriteLine(Test("Test1"));
            }
      }
}

================ Class1.cs ends

Behind the scenes, Interop converts C# System.String to char*, marshalls it to test(), and creates System.String out of the returned char*.

You may also read "extern (C#)" help topic. Please note that "Here is what I would write in DllTest if it was C#" part of your request is not satisfied. Test() does not do what you requested, it just looks like doing it.  
0
 
RodionPAuthor Commented:
No it does not work for some reason,

I am not a C++ developer, but I have this C++ code that I have to port to my C# code, that C++ code is written in Visual Studio 6, I need to be able to call 1 function from all that C++ code, and it is a very simple function, it takes string as a parameter and returns string as a parameter, I tried using above example and it keeps telling me that it cannot find an entry point.

Please, assume I am stupid and explain in details, all I care is to pass a string down to C++ code and retrieve a string that that C++ code produces.

I raised the points to a maximum...
0
 
melodiesoflifeCommented:
Hi RodionP

First of all, The keyword string for VC ++ 6.0 isn't: string. You must use "CString" or "char*"
2nd: You dll code don't have Dll entry point.

Here is the example for you to create Win32 dll in VC++6.0

//*******************************//
#include "stdafx.h"
// Entry point function.
BOOL APIENTRY DllMain( HANDLE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                               )
{
    switch (ul_reason_for_call)
      {
            case DLL_PROCESS_ATTACH:
            case DLL_THREAD_ATTACH:
            case DLL_THREAD_DETACH:
            case DLL_PROCESS_DETACH:
                  break;
    }
    return TRUE;
}

__declspec(dllexport) char *fnDllExample(char* cMyString)
{
      //return "Hello";
               return strcat(cMyString, " - Hello");
}

0
 
OctabunCommented:
BTW, what fails: the example code or your code that follows the example?  Let us find out where exactly you are.

Step 1. Using interop.

The "extern (C#)" help topic shows how to call MessageBox windows function:

=== Help example starts

Example

In this example, the program receives a string from the user and displays it inside a message box. The program uses the MessageBox method imported from the User32.dll library.

using System;
using System.Runtime.InteropServices;
class MyClass
{
   [DllImport("User32.dll")]
   public static extern int MessageBox(int h, string m, string c, int type);

   public static int Main()
   {
      string myString;
      Console.Write("Enter your message: ");
      myString = Console.ReadLine();
      return MessageBox(0, myString, "My Message Box", 0);
   }
}

Sample Run

Enter your message: Where do you want to go today?
When the previous text is entered, a message box that contains the text will pop up on the screen.

==== Help exampl ends

Can you run this example?

Step 2. Passing string and getting string.

Can you run my example? It is very close to the second example in "extern (C#)", but uses the DEF file to export Test(), which is more fool proof than __declspec(dllexport).

If you cannot, then why: No C++ installed in VS.NET, no skill to create a DLL, etc.

Step 3. Calling a function in your DLL.

Possibly after the first 2 steps your problem is solved. If not:

Do you have source code for your DLL? Do you have a .h file with the definition of the function you want to call or somebody just told you what it is? Can you compile the DLL? Can you see what functions are exported from a DLL?
 
I use TotalCommander (http://www.ghisler.com) with the File Info plugin (http://physio-a.univ-tours.fr/tcplugins/) to do see the functions exported by a dll, but there should be other means also.

The problem is that there is no such thing as "string" built into C/C++. However, there are class libraries that can have classes called "String". So, it is necessary to check what EXACTLY the functon you are trying to call looks like. The "it takes string as a parameter and returns string as a parameter" description is not enough.

Where we go from here depends on what you have and can.

For example:

- if you have everything you need, check the name, declaration (should be as in the example), and the fact that the function is exported. Compile the DLL. Check that the function is actually exported. Call it from C#.

- if the function is not char * (char *), then write a wrapper around it which is and call the wrapper.

- if the function is defined like __declspec(dllexport) char * Test2 (char * p) {...}, then you may add the entry point number to C# like [DllImport("TestDLL.dll", EntryPoint="#3")].
0
 
RodionPAuthor Commented:
I will try that, thank you for your response, I'll try to answer asap
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Introducing Cloud Class® training courses

Tech changes fast. You can learn faster. That’s why we’re bringing professional training courses to Experts Exchange. With a subscription, you can access all the Cloud Class® courses to expand your education, prep for certifications, and get top-notch instructions.

  • 4
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now