Link to home
Start Free TrialLog in
Avatar of RodionP
RodionP

asked on

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
Avatar of Octabun
Octabun

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.
Avatar of RodionP

ASKER

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
Avatar of RodionP

ASKER

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
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.  
Avatar of RodionP

ASKER

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...
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");
}

ASKER CERTIFIED SOLUTION
Avatar of Octabun
Octabun

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of RodionP

ASKER

I will try that, thank you for your response, I'll try to answer asap