英文:
Can not parse a string from C++ to C#
问题
I write a C# dll and call it from C++ function. But when I parse a string from C++ to C# function, I will show something weird like this:
> d^¡Aè☺
Here is my C++ code:
#include "pch.h"
#include<stdio.h>
#include<Windows.h>
#include<string>
using namespace System;
using namespace System::Runtime::InteropServices;
using namespace System::Reflection;
int main()
{
const char* pemodule = ("C:\\Users\\source\\repos\\ClassLibrary2\\ClassLibrary2\\bin\\Debug\\ClassLibrary2.dll");
HMODULE hlib = LoadLibraryA(pemodule);
typedef int(__cdecl *add)(int a, int b);
typedef int(__cdecl* AntiMacro)(std::string path);
auto pAntiMacro = (AntiMacro)GetProcAddress(hlib, "AntiMacro");
std::string path = "C:\\macro\\test";
int a = pAntiMacro(path);
printf("%d\n", a);
return 0;
}
And here is my C# DLL:
[DllExport]
public static int AntiMacro(string filepath)
{
Console.WriteLine(filepath);
bool isFolder = false;
string fullpath = "";
try
{
fullpath = Path.GetFullPath(filepath);
Console.WriteLine(fullpath.ToString());
}
catch (Exception)
{
Console.WriteLine(fullpath);
Console.WriteLine("Invalid path 1");
return 1;
}
I tried to change
std::string path = "C:\\macro\\test"
to
const char *path = "C:\\macro\\test"
But it still not working, is that string in C++ is different from C#?
英文:
I write a C# dll and call it from C++ function. But when i parse a string from C++ to C# function, i will show something weird like this:
> d^¡Aè☺
Here is my C++ code:
#include "pch.h"
#include<stdio.h>
#include<Windows.h>
#include<string>
using namespace System;
using namespace System::Runtime::InteropServices;
using namespace System::Reflection;
int main()
{
const char* pemodule = ("C:\\Users\\source\\repos\\ClassLibrary2\\ClassLibrary2\\bin\\Debug\\ClassLibrary2.dll");
HMODULE hlib = LoadLibraryA(pemodule);
typedef int(__cdecl *add)(int a, int b);
typedef int(__cdecl* AntiMacro)(std::string path);
auto pAntiMacro = (AntiMacro)GetProcAddress(hlib, "AntiMacro");
std::string path = "C:\\macro\\test";
int a = pAntiMacro(path);
printf("%d\n", a);
return 0;
}
And here is my C# DLL:
[DllExport]
public static int AntiMacro(string filepath)
{
Console.WriteLine(filepath);
bool isFolder = false;
string fullpath = "";
try
{
fullpath = Path.GetFullPath(filepath);
Console.WriteLine(fullpath.ToString());
}
catch (Exception)
{
Console.WriteLine(fullpath);
Console.WriteLine("Invalid path 1");
return 1;
}
I tried to change
std::string path = "C:\\macro\\test"
to
const char *path = "C:\\macro\\test"
But it still not working, is that string in C++ is different from C#?
答案1
得分: 3
你首先需要将 std::string
转换为 char*
std::string path = "C:\\macro\\test";
const char *cstr = path.data();
int a = pAntiMacro(cstr);
你还需要为字符串进行编组
[DllExport]
public static int AntiMacro(
[MarshalAs(UnmanagedType.LPStr)]
string filepath)
{
但使用 C++/CLI 可能是更好的选择。
英文:
You first need to convert std:string
into char*
std::string path = "C:\\macro\\test";
const char *cstr = path.data();
int a = pAntiMacro(cstr);
You also need marshalling for the string
[DllExport]
public static int AntiMacro(
[MarshalAs(UnmanagedType.LPStr)]
string filepath)
{
But using C++/CLI might be a better option either way.
答案2
得分: 2
To work with C# DLLs in C++, you need to use the .NET Framework's Common Language Runtime (CLR) and interact with the DLL through managed interop: https://learn.microsoft.com/en-us/cpp/dotnet/overview-of-marshaling-in-cpp?view=msvc-170
Also see this: https://stackoverflow.com/questions/3539334/how-to-turn-systemstring-into-stdstring https://stackoverflow.com/a/53016935/5033623
I highly do not recommend this approach though unless you have a very specific reason to work with C# API calls in your native application. It's usually the other way around.
英文:
To work with C# DLLs in C++, you need to use the .NET Framework's Common Language Runtime (CLR) and interact with the DLL through managed interop:
https://learn.microsoft.com/en-us/cpp/dotnet/overview-of-marshaling-in-cpp?view=msvc-170
Also see this:
https://stackoverflow.com/questions/3539334/how-to-turn-systemstring-into-stdstring
https://stackoverflow.com/a/53016935/5033623
I highly do not recommend this approach though unless you have a very specific reason to work with C# API calls in your native application. It's usually the other way around.
答案3
得分: 0
UPDATE: 我找到了解决方案。正如Charlieface所说:我需要将这段代码放入我的代码中:
[DllExport]
public static int AntiMacro(
[MarshalAs(UnmanagedType.LPStr)]
string filepath)
{
但仍然无法正常工作,所以我稍微修改了它:
[DllExport]
public static int AntiMacro(
[MarshalAs(UnmanagedType.LPUTF8Str)]
string filepath)
我将UnmanagedType.LPStr更改为UnmanagedType.LPUTF8Str,它完美运行。并根据Charlieface提供的建议编辑了我的C++代码。
英文:
UPDATE: i found the solution. As Charlieface said: i need to put this in my code:
[DllExport]
public static int AntiMacro(
[MarshalAs(UnmanagedType.LPStr)]
string filepath)
{
But it still not working, so i rewrite it a little bit:
[DllExport]
public static int AntiMacro(
[MarshalAs(UnmanagedType.LPUTF8Str)]
string filepath)
I change UnmanagedType.LPStr to UnmanagedType.LPUTF8Str and it work perfectly. And edit my C++ code as Charlieface provided.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论