C#Dll导入Go Dll字符串值差异-CString返回值
我在Go中编写了一个dll,用公钥/私钥编码对数据进行解密/加密 我遇到的第一个问题是在dll和c代码之间共享字符串 我通过使用Go中的C库解决了这个问题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
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;
}