简体   繁体   中英

How to call C ++ method in C # using Invoke

Am I doing it right? I have two projects in parallel, the first is code that was made in C ++ and the second project (Console made in AspNetCore v3.1) is the attempt to call the method that is in C ++ code. I need to call the C ++ method "Decrypt" in the C # project. How do I do that?

C++ code

#include <stdlib.h>
#include <string.h>
#include<windows.h>
#include "bascript.hpp"

extern "C"
int FAR PASCAL _export
Decript( const LPSTR name, const LPSTR passwordWithCript,
             LPSTR passwordWithoutCript, unsigned int sizeSpaceRetorn ) {

    LPSTR result = lpDecript( name, passwordWithCript);
    if ( sizeSpaceRetorn < strlen(result) )
       return 0;
       
    strcpy( passwordWithoutCript, result );
    delete result;
    return 1;
}

C#

class Program
{
    [DllImport(@"C:\MS\VS\TesteDLLCentura\TesteDLLCentura\bin\Debug\netcoreapp3.1\Sises.DLL", CharSet = CharSet.Auto, EntryPoint = "Decript")]
        private static extern string Decript(string name, string passwordWithCript, string passwordWithoutCript, uint sizeSpaceRetorn);

        static void Main(string[] args)
        {
            string retorno = Decript("<user>", "<cript_password>", "", 0);
            Console.WriteLine(retorno);

            Console.ReadLine();
        }
}

You can return a pointer from native world (C/C++, etc.) as long as you use a .NET compatible memory allocator. On Windows, that would be the COM Allocator.

So here are 3 ways to return a string: Ansi, Unicode and BSTR (unicode). Note: you should avoid using Ansi on Windows.

C++ side:

extern "C"  __declspec(dllexport) void* DecryptA(const char* name, const char* password)
{
    char str[] = "hello ansi world";
    int size = (lstrlenA(str) + 1) * sizeof(char); // terminating zero

    // use .NET compatible allocator
    void* buffer = CoTaskMemAlloc(size);
    CopyMemory(buffer, str, size);
    return buffer;
}

extern "C"  __declspec(dllexport) void* DecryptW(const wchar_t* name, const wchar_t* password)
{
    wchar_t str[] = L"hello unicode world";
    int size = (lstrlenW(str) + 1) * sizeof(wchar_t); // terminating zero

    // use .NET compatible allocator
    void* buffer = CoTaskMemAlloc(size);
    CopyMemory(buffer, str, size);
    return buffer;
}

extern "C"  __declspec(dllexport) BSTR DecryptBSTR(const wchar_t* name, const wchar_t* password)
{
    wchar_t str[] = L"hello BSTR world";

    // use .NET compatible allocator and COM coolness
    return SysAllocString(str);
}

C# side:

[DllImport("mydll", CharSet = CharSet.Ansi)]
private static extern string DecryptA(string name, string password);

[DllImport("mydll", CharSet = CharSet.Unicode)]
private static extern string DecryptW(string name, string password);

[DllImport("mydll", CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.BStr)]
private static extern string DecryptBSTR(string name, string password);

...

static void Main()
{
    Console.WriteLine(DecryptA("name", "password"));
    Console.WriteLine(DecryptW("name", "password"));
    Console.WriteLine(DecryptBSTR("name", "password"));
}

Your C++ function does not return a string or equivalent. It returns an int result (success or failure), and the actual result goes in the passwordWithoutCript buffer.

So you need to create the buffer and pass it in.

Because you are using LPSTR on the C++ side, you need CharSet.Ansi :

[DllImport(@"C:\MS\VS\TesteDLLCentura\TesteDLLCentura\bin\Debug\netcoreapp3.1\Sises.DLL", CharSet = CharSet.Ansi, EntryPoint = "Decript")]
private static extern int Decript(string name, string passwordWithCript, StringBuilder passwordWithoutCript, uint sizeSpaceRetorn);

static void Main(string[] args)
{
    var sb = new StringBuilder(1000);  // or whatever size
    if(Decript("<user>", "<cript_password>", sb, sb.Length) == 1)
        Console.WriteLine(retorno);

    Console.ReadLine();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM