c# - 为什么 C# 编码字符串不能与 C++ DLL 一起使用

标签 c# c++ dll

我在将字符串传递到外部 DLL 中的某个函数时遇到问题。我会发布一个实际的代码片段,但它有点困惑并且可能难以阅读。以下片段是我个人代码的归结。

C# 文件 (UNICODE)

[DllImport("InjectDll.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
private static extern ulong FindProgramProcessId(string procName);
[DllImport("InjectDll.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
private static extern bool InjectIntoProcess(ulong procId, string Dll);
string ProcName = "random_test_game.exe";
string DllPath = @"C:\ProgramData\Hack\File.dll";
ulong procId = FindProgramProcessId(ProcName);
bool Injected = InjectIntoProcess(procId, DllPath);

C++ 文件 (ANSI)

DllExport DWORD FindProgramProcessId(const char* procName)
{
    ...
}
DllExport bool InjectIntoProcess(DWORD procId, const char* Dll)
{
    if (Dll == nullptr)
    {
        MessageBox(NULL, "DLL", "EMPTY", MB_OK);
        return false;
    }
    ...
}

C++ 头文件

#pragma once
#include <Windows.h>
#include <TlHelp32.h>
#include <string>
#ifdef EXPORT
#define DllExport __declspec(dllexport)
#else
#define DllExport __declspec(dllimport)
#endif
extern "C" DllExport DWORD FindProgramProcessId(const char* procName);
extern "C" DllExport bool InjectIntoProcess(DWORD procId, const char* Dll);

引用片段,出现的问题是 FindProgramProcessId 将成功传递一个字符串,没问题,但 InjectIntoProcess 将根据“我在该方法中放入的额外”代码。

注意,我已经尝试传递 IntPtr 代替 string 并使用 Marshal.StringToHGlobalAnsi,但我仍然得到 Dll == nullptr 问题。它破坏了我的代码。可以在我的 GuidedHacking 中找到更多相同的信息。线程。

最佳答案

Win32 DWORD 是 32 位整数,但 C# ulong 是 64 位整数。混淆源于 DWORDunsigned long 的别名,但 C++ long 不一定是 64 位(事实上,在 MSVC 中,它是 32 位;unsigned long long 是 64 位无符号整数)。

由于您使用的是 cdecl 调用约定,调用者负责清理堆栈(因此不会发生崩溃),并且参数从右到左传递(因此 Dll 最终指向在传递给 procId 的值的中间某处,它可能包含零)。或者至少这是我的猜测,因为我们在这里处于未定义的行为领域。

您应该将 FindProgramProcessId 的返回值和 InjectIntoProcessprocId 参数声明为 uint

关于c# - 为什么 C# 编码字符串不能与 C++ DLL 一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57044791/

相关文章:

c# - 无法使用 MS .NET 运行时运行 GTK# 应用程序,只能使用 Mono 运行

c# - 是否可以根据正则表达式模式生成示例字符串?

c++ - 尝试对 g++ 进行颜色编码

vb.net - 无法加载文件或程序集 System.Data.SQLite - Windows 应用程序

c++ - 使用 dll、pdb 文件和源代码在 VS C++ 中调试

带条件的 C++ 模板非类型参数

c# - SonarQube MSBuild runner 中的编程覆盖排除

c# - 如果使用 LINQ 键存在,则从字典中选择值

C# 工厂设计模式

c++ - bada 编程 - 按钮事件处理程序