C# 如何绕过DLL调用使其返回自定义固定15字节数组?
方案解答
首先确认你的理解是正确的:上层代码传入14字节数组首地址、1字节数组首地址,非托管方法会向两个连续内存块写入合计15字节数据,对应你说的14位时间戳+1位数字的格式。
方案1:替换C#原生方法声明(零业务代码改动)
仅需要修改state方法定义所在的静态类,所有上层调用代码完全不用调整,适配90%以上的场景:
- 找到原来定义
DllImport的静态类(通常是NativeMethods这类公共类),删掉原有extern声明,替换为自定义实现:
public static class NativeMethods { // 删掉原来的DllImport声明,替换为以下实现 public static unsafe int state(ref byte ktime, ref byte is_h) { // 替换为你需要返回的15位目标字符串,前14位为YYYYMMDDHHMMSS格式时间,最后1位为0-7的数字 string targetData = "202112060141307"; byte[] dataBytes = System.Text.Encoding.ASCII.GetBytes(targetData); fixed (byte* pKtime = &ktime) { // 复制前14字节到ktime指向的数组内存 for (int i = 0; i < 14; i++) { pKtime[i] = dataBytes[i]; } } fixed (byte* pIsH = &is_h) { // 复制最后1字节到is_h指向的内存 *pIsH = dataBytes[14]; } // 替换为原DLL正常返回的状态码即可 return 0; } }
- 开启项目的不安全代码权限:右键项目 → 属性 → 生成 → 勾选「允许不安全代码」即可。
方案2:制作同名垫片DLL(零C#代码改动)
如果DllImport声明散落在项目各处,或者你完全不想修改任何C#代码,可以自己编译一个同名的asd.dll替换原有DLL即可:
- 新建C++ DLL项目,项目名设置为
asd,添加导出函数实现:
#include <cstring> extern "C" __declspec(dllexport) int __cdecl state(unsigned char* ktime, unsigned char* is_h) { // 替换为你需要返回的15位目标字符串 const char* target_data = "202112060141307"; // 写入14位时间戳到ktime指向的内存 memcpy(ktime, target_data, 14); // 写入最后1位数字到is_h指向的内存 *is_h = target_data[14]; // 替换为原DLL正常返回的状态码 return 0; }
- 编译生成对应架构(x86/x64要和原DLL一致)的
asd.dll,直接替换原有DLL即可生效,不需要修改任何C#代码。
内容的提问来源于stack exchange,提问作者user3806904
相关产品推荐
相关产品推荐

