如何调用C++;C#中使用Invoke的方法

如何调用C++;C#中使用Invoke的方法,c#,c++,asp.net-core,console,pinvoke,C#,C++,Asp.net Core,Console,Pinvoke,我做得对吗?我有两个并行的项目,第一个是用C++编写的代码,第二个项目(用AspNetCore v3.1编写的控制台)是试图调用C++代码中的方法。 我需要在C#项目中调用C++方法“Decrypt”。我该怎么做 C++代码 #include <stdlib.h> #include <string.h> #include<windows.h> #include "bascript.hpp" extern "C" int

我做得对吗?我有两个并行的项目,第一个是用C++编写的代码,第二个项目(用AspNetCore v3.1编写的控制台)是试图调用C++代码中的方法。 我需要在C#项目中调用C++方法“Decrypt”。我该怎么做

C++代码

#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;
}
#包括
#包括
#包括
#包括“bascript.hpp”
外部“C”
int FAR PASCAL\u导出
Decript(常量LPSTR名称,常量LPSTR密码WithScript,
LPSTR密码,不带符号,整数大小不带符号){
LPSTR result=lpDecript(name,passwordwithscript);
如果(尺寸/体积小于斯特伦(结果))
返回0;
strcpy(带输出的密码,结果);
删除结果;
返回1;
}
C#

类程序
{
[DllImport(@“C:\MS\VS\TesteDLLCentura\TesteDLLCentura\bin\Debug\netcoreapp3.1\Sises.DLL”,CharSet=CharSet.Auto,EntryPoint=“Decript”)]
私有静态外部字符串描述(字符串名称、字符串密码WithScript、字符串密码WithOutscript、uint SIZESPACETRON);
静态void Main(字符串[]参数)
{
字符串编号=Decript(“,”,“,”,0);
控制台写入线(retorno);
Console.ReadLine();
}
}

只要使用与.NET兼容的内存分配器,就可以从本机世界(C/C++等)返回指针。在Windows上,这将是COM分配器

这里有3种返回字符串的方法:Ansi、Unicode和BSTR(Unicode)。注意:应避免在Windows上使用Ansi

C++方面:

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侧:


<>强>您的C++函数不返回<代码>字符串< /> >或等效。它返回一个
int
结果(成功或失败),实际结果放入
passwordwithoutript
缓冲区。

因此,您需要创建缓冲区并将其传入

因为在C++端使用<代码> LpSTR ,需要<代码>字符集.ANSI >:

[DllImport(@“C:\MS\VS\TesteDLLCentura\TesteDLLCentura\bin\Debug\netcoreapp3.1\Sises.DLL”,CharSet=CharSet.Ansi,EntryPoint=“Decript”)]
私有静态外部指令(字符串名称、字符串密码WithScript、StringBuilder密码WithOutscript、uint SIZESPACETRON);
静态void Main(字符串[]参数)
{
var sb=新的StringBuilder(1000);//或任意大小
如果(Decript(“,”,sb,sb.长度)==1)
控制台写入线(retorno);
Console.ReadLine();
}

您是否尝试过使用相对路径?例如,
[DllImport(“Sises.dll”,CharSet=CharSet.Auto,EntryPoint=“Decript”)]
@Timothy G,无论有无相对路径,它都会给出错误。(进程27840)已退出,代码为-1073740940。您需要声明
StringBuilder密码WithOutscript
,将其预初始化为某个大小,然后将该大小传递到
sizeSpaceRetorn
。这将包含实际结果,以NUL(0)字符结尾。返回类型应该是
int
not
string
即使根据上面的代码进行更改,应用程序也会返回以下消息:“此表达式会产生副作用,不会被计算”。该消息是一条调试器消息,告诉您它不会从监视窗口或即时窗口执行某些类型的代码。您将需要实际执行它。您是否收到了实际错误?
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);
}
[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"));
}