小能豆

C#调用C++动态库闪退

C#

这段调用读取身份证信息的代码有没有什么问题,感谢感谢。
[DllImport(dllPath, EntryPoint = “iReadIdentityCard”, CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern int ReadSFZNew(ref int piFingerLen, ref byte[] pucFinger, byte[] pOutInfo);

try
{
int len = 1024;
byte[] szInputParams = new byte[1024];
byte[] newbyte = new byte[102400];
int a = (Int16)ReadSFZNew(ref len, ref szInputParams, newbyte);
MessageBox.Show(“a” + a.ToString());
string pCardInfo = System.Text.Encoding.Default.GetString(szInputParams);
pCardInfo = pCardInfo.Replace(‘\0’, ‘ ‘).Trim();
string pBusiCardInfo = System.Text.Encoding.Default.GetString(newbyte);
pBusiCardInfo = pBusiCardInfo.Replace(‘\0’, ‘ ‘).Trim();
if (a == 0)
{
this.textBox1.Text = pBusiCardInfo;
}
else
{
this.textBox1.Text = a.ToString();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}

C#调用C++

问题补充:这个是c++头文件的内容:
long __stdcall iReadIdentityCard(int piFingerLen, unsigned char pucFinger, char* pOutInfo);


阅读 46

收藏
2024-06-01

共1个答案

小能豆

在C#中调用C的函数时,需要确保参数类型和数量与C函数的声明完全匹配。在你提供的代码中,有几个问题需要注意:

  1. ref byte[] 应该是 ref byte,因为C++函数中的 pucFinger 是一个指向 unsigned char 的指针,而不是一个 unsigned char 数组。

  2. ReadSFZNew 函数的第三个参数应该是一个指向 char 数组的指针,而不是 byte[] 数组。你需要将其声明为 byte* 或者 sbyte*

  3. C++函数声明中的 long 在C#中对应的是 Int32

修改后的代码应该如下所示:

[DllImport(dllPath, EntryPoint = "iReadIdentityCard", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern Int32 ReadSFZNew(ref Int32 piFingerLen, ref byte pucFinger, byte* pOutInfo);

try
{
    int len = 1024;
    byte szInputParams = 0; // 修改为单个字节的引用
    byte[] newbyte = new byte[102400];
    fixed (byte* pNewbyte = newbyte)
    {
        Int32 a = ReadSFZNew(ref len, ref szInputParams, pNewbyte);
        MessageBox.Show("a" + a.ToString());
        string pCardInfo = System.Text.Encoding.Default.GetString(&szInputParams, len); // 使用len参数指定长度
        pCardInfo = pCardInfo.Replace('\0', ' ').Trim();
        string pBusiCardInfo = System.Text.Encoding.Default.GetString(newbyte);
        pBusiCardInfo = pBusiCardInfo.Replace('\0', ' ').Trim();
        if (a == 0)
        {
            this.textBox1.Text = pBusiCardInfo;
        }
        else
        {
            this.textBox1.Text = a.ToString();
        }
    }
}
catch (Exception ex)
{
    MessageBox.Show(ex.Message);
}

注意:在使用 unsafe 代码时,需要启用项目设置中的 “Allow unsafe code” 选项。此外,在使用指针时要特别小心,确保不会导致内存泄漏或错误。

2024-06-01