c# - 编码 native 函数

标签 c# c pinvoke marshalling

我在 C DLL 中有一个执行 SCrypt key 派生的函数,但我在将这些值编码到我的 C# 程序中时遇到了真正的麻烦。

C中的函数声明如下:

__declspec(dllexport) int scrypt(const uint8_t * passwd, size_t passwdlen, const uint8_t * salt, size_t saltlen, uint64_t N, uint32_t r, uint32_t p,uint8_t * buf, size_t buflen);

passwd 和 salt 都通过指向 uint8 数组的指针传递,N、r 和 p 是算法的调整值。 Buflen 是您希望输出缓冲区的大小。 buf 是输出缓冲区(因此我认为需要是 ref 或 out);

我尝试了各种方法,最近的方法是 Marshal.Copy 将数据从 IntPtr 移到字节数组(反之亦然),但是因为这些是 UInt 指针而不是 IntPtr 我不知道如果那是对的。目前,当我尝试将数据从 buf IntPtr 复制回数组时,它会崩溃。

如果有任何帮助,我将不胜感激。

class Program
{
    [DllImport("SCrypt.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
    public static extern int scrypt(IntPtr passwd, UIntPtr passwdlen, IntPtr salt, UIntPtr saltlen, UInt64 N, UInt32 r, UInt32 p, out IntPtr buf, UIntPtr buflen);

    static void Main(string[] args)
    {
        byte[] encoded = new byte[32];
        IntPtr encodedptr;

        byte[] password = System.Text.Encoding.Unicode.GetBytes("test");
        byte[] salt = System.Text.Encoding.Unicode.GetBytes("ThisistheSaltweareusingforthiskey");
        IntPtr passwordptr, saltptr;

        passwordptr = Marshal.AllocHGlobal(password.Length);
        Marshal.Copy(password, 0, passwordptr, password.Length);

        saltptr = Marshal.AllocHGlobal(salt.Length);
        Marshal.Copy(salt, 0, saltptr, salt.Length);

        int returnVal = scrypt(passwordptr, (UIntPtr)password.Length, saltptr, (UIntPtr)salt.Length, 262144, 8, 1,out encodedptr,(UIntPtr) 32);

        Marshal.Copy(encodedptr, encoded, 0, 32);

        Console.WriteLine(BitConverter.ToString(encoded));
        Console.ReadKey();
    }
}

最佳答案

我可能会使用以下函数声明:

public static extern int scrypt(byte[] passwd, uint passwdlen, byte[] salt, uint saltlen, ulong N, uint r, uint p, byte[] buf, uint buflen).

请记住,有多种不同的方法来编码某些类型,但在这种情况下,上述变体可能是最清晰的,因为它直接映射到相应的类型。

您可以通过请求 Encoding 为您完成此操作,将 string 简单地转换为 byte[]。对于密码,只要您将其转换为 Unicode,一切都应该没问题。但请确保在可能需要将密码转换为 byte[]每个地方使用相同的变体。

关于c# - 编码 native 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24799691/

相关文章:

c - 队列字母无效

c - 读取 C 中的 bin 文件未按预期工作

c# - 将动态大小数组编码到结构中

c# - c++从hbitmap获取原始像素数据

c# - 按顺序重命名多个文件 c# 或 c++

c# - 将字母转换为其字母数字等级

c - 读写并发

c# - PInvoke 和德尔福

c# - 根据程序内存查找新地址

c# - 抽象属性是否创建私有(private)支持字段?