【问题标题】:How to correctly marshal unsigned char* from c dll to c#如何正确地将 unsigned char* 从 c dll 编组到 c#
【发布时间】:2019-07-19 15:13:45
【问题描述】:

我正在尝试准备一个简单的基于 GUI 的 AES-CMAC 计算器。为此,我决定从开放的 ssl 库中创建 c dll。[我不想使用 .net 来计算 AES-CMAC]。这个 DLL ,我已经使用在 c++(console) 中创建的测试应用程序进行了测试,并且生成的值是根据测试向量。但是当我试图从 c# 调用这个函数时,我得到了错误的值。这里我使用的是 byte[] 而不是 unsigned char*。

我的 c 函数代码 sn-p 是

double calc_AES_CMAC(unsigned char* message ,unsigned char* key,unsigned char* cmac_16)
{

    size_t mactlen;

    CMAC_CTX *ctx = CMAC_CTX_new();
    CMAC_Init(ctx, key, 16, EVP_aes_128_cbc(), NULL);
    CMAC_Update(ctx, message, sizeof(message));
    CMAC_Final(ctx, cmac_16, &mactlen);
    CMAC_CTX_free(ctx);

    return 0;
}

而我的调用 C# 代码是

首先是函数导入

[DllImport("C:\\Users\\Sudhanwa\\Documents\\Visual Studio 2010\\Projects\\Ccsharpdll\\Debug\\Ccsharpdll.dll", CallingConvention = CallingConvention.Cdecl)]

public static extern double calc_AES_CMAC(byte[] message, byte[] key, byte[] output);

二次按钮点击事件

byte [] null_arr = new byte[16];
// K: 2b7e1516 28aed2a6 abf71588 09cf4f3c
byte[] key = { 0x2b,0x7e,0x15,0x16,
0x28,0xae,0xd2,0xa6,
0xab,0xf7,0x15,0x88,
0x09,0xcf,0x4f,0x3c };

// M: 6bc1bee2 2e409f96 e93d7e11 7393172a Mlen: 128
byte[] message= { 0x6b,0xc1,0xbe,0xe2,
0x2e,0x40,0x9f,0x96,
0xe9,0x3d,0x7e,0x11,
0x73,0x93,0x17,0x2a };

byte [] cmac = new byte [16];

c = calc_AES_CMAC(message, key, cmac);
string ans = ByteArrayToString(cmac);
MessageBox.Show(ans);

在这段代码中,我得到 16 字节的十六进制输出,但这与正确的结果不匹配。

【问题讨论】:

  • 你检查字符串编码了吗?
  • 不,我没有检查字符串编码。能否请您详细介绍一下?
  • CMAC_Update(ctx, message, sizeof(message)); 是垃圾。 sizeof(message) 是数组的大小。试试 16。
  • @AnttiHaapala 它有效..结果现在匹配

标签: c# c++ c


【解决方案1】:

您需要向编组器表明您希望在输出参数中返回数据(以及多少数据):

public static extern double calc_AES_CMAC(byte[] message, byte[] key, 
    [In, Out, MarshalAs(UnmanagedType.LPArray, SizeConst=16)] byte[] output);

否则,数组当前内容的副本将被传递给 C++ 函数,但任何修改都不会被复制回 C# 调用者。

【讨论】:

  • 试过这个 --public static extern double calc_AES_CMAC(byte[] message, byte[] key, [In, Out, MarshalAs(UnmanagedType.LPArray, SizeConst=16)] byte[] output);但仍然得到不正确的结果
  • 您确定 calc_AES_CMAC 工作正常吗?见安蒂评论。最好先用 C++ 非托管代码中的测试验证函数。
  • 是的,这个函数已经过验证,并且可以与 c++ 驱动程序应用程序一起使用。我已经引用了这个链接,并且可以完美运行...stackoverflow.com/questions/28354844/…你可以在这篇文章中找到正确的预期输出
  • 不,在引用的代码中,消息是unsigned char[],在您的代码中是unsigned char*sizeof(message) 在这些情况下会有很大不同。请看一下 Antti 的评论。
猜你喜欢
  • 2010-12-17
  • 2011-04-29
  • 2020-10-11
  • 2017-01-05
  • 2012-02-14
  • 1970-01-01
  • 2013-02-02
  • 2014-07-21
  • 1970-01-01
相关资源
最近更新 更多