Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/305.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#Dll导入Go Dll字符串值差异-CString返回值_C#_Go_Dll_Encoding_C Strings - Fatal编程技术网

C#Dll导入Go Dll字符串值差异-CString返回值

C#Dll导入Go Dll字符串值差异-CString返回值,c#,go,dll,encoding,c-strings,C#,Go,Dll,Encoding,C Strings,我在Go中编写了一个dll,用公钥/私钥编码对数据进行解密/加密 我遇到的第一个问题是在dll和c代码之间共享字符串 我通过使用Go中的C库解决了这个问题 func myfunc( password *C.char, passwordLength C.int ) *C.char{ result = C.GoStringN(password, passwordLength) return C.CString(result) } 差不多是这样的 在C中,对应的是 Marshal.Pt

我在Go中编写了一个dll,用公钥/私钥编码对数据进行解密/加密

我遇到的第一个问题是在dll和c代码之间共享字符串

我通过使用Go中的C库解决了这个问题

func myfunc( password *C.char, passwordLength C.int )  *C.char{
   result = C.GoStringN(password, passwordLength)
   return C.CString(result)
}
差不多是这样的

在C中,对应的是

Marshal.PtrToStringAuto(value);
现在我的问题是go和c中的字符串不匹配。一个函数返回一个加密值,当我用

fmt.println(...)
它与我在c#中记录的返回值不匹配

我尝试了不同的功能:

Marshal.PtrToStringAuto(...)
Marshal.PtrToStringAnsi(...)
Marshal.PtrToStringUTF8(...)
Marshal.PtrToStringUni(...)
在使用C库之后,我对go中的字符串也有问题。由于这个原因,我添加了length并从C.GoString迁移到C.GoString,这在调试Go中的代码时很有帮助

我真的不知道我做错了什么。有人知道我可以尝试什么吗

我解决了部分问题。加密的输出具有定义的大小。因此,在Go中,我现在能够正确读取值。 我在C#中有哪些选项可以正确读取值?
从封送函数来看,Marshal.PtrToStringUTF8似乎工作得最好。但它不等于Go的值。

这里是一个在Go dll中使用AES加密的示例;字符串与我匹配:

Go代码(编译时启用CGO_=1 GOARCH=386 GOOS=windows Go build-buildmode=c-shared-o test.dll AES.Go):


谢谢你帮助我

你的解决方案对我不起作用,但对我帮助很大

//export EncryptForDb
func EncryptForDb(value *C.char) unsafe.Pointer {
   encodedString := Cipher.PrivatKeyEncryptValue(Cipher.PrivatKey, C.GoString(value))
   return C.CBytes([]byte(encodedString))
}
我返回一个指向结果ByteArray的不安全指针。在C方面,我现在正在使用这个代码

byte[] ICipherManager.EncryptForDb(string value)
{
    byte[] encryptedBytes = new byte[1024];

    IntPtr pointer = EncryptForDb(value);
    Marshal.Copy(pointer, encryptedBytes, 0, encryptedBytes.Length);

    return encryptedBytes;
}
当im使用C.CString时,原始值被切片。 Go和C#字符串确实包含长度属性。CString由ram终止,我找不到一个解决方案来读取或写入整个加密字符串。所以我决定改用[]字节

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            var encrypted = GoFunctions.Encrypt(System.Text.Encoding.UTF8.GetBytes("hello"));
            var decrypted = GoFunctions.Decrypt(System.Text.Encoding.UTF8.GetBytes(Marshal.PtrToStringAnsi(encrypted)));
            label1.Text = Marshal.PtrToStringAnsi(encrypted);
            label2.Text = Marshal.PtrToStringAnsi(decrypted);
        }

        static class GoFunctions
        {
            [DllImport(@"C:\Repos\Go_AES\test.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
            public static extern IntPtr Encrypt(byte[] message);

            [DllImport(@"C:\Repos\Go_AES\test.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
            public static extern IntPtr Decrypt(byte[] encrypted_message);
        }
    }
}
//export EncryptForDb
func EncryptForDb(value *C.char) unsafe.Pointer {
   encodedString := Cipher.PrivatKeyEncryptValue(Cipher.PrivatKey, C.GoString(value))
   return C.CBytes([]byte(encodedString))
}
byte[] ICipherManager.EncryptForDb(string value)
{
    byte[] encryptedBytes = new byte[1024];

    IntPtr pointer = EncryptForDb(value);
    Marshal.Copy(pointer, encryptedBytes, 0, encryptedBytes.Length);

    return encryptedBytes;
}