我在VB6中有一些代码从dll导入函数,它使用byVal和byRef关键字,我想将该代码转换为C#3.5。
字符串的unicode编码是否会出现问题?
我是否将vb6中“byRef”的变量声明为C#代码中的“ref”变量?
接收返回值被输入VB6代码发送的字符串中作为“byVal”参数,如果你想允许,你应该如何发送东西“byRef”编辑字符串的功能?这个概念是否仍适用于我的C#代码?
我尝试从VB6处理函数声明,参数类型只是int,long和string。哪里有一个“byVal”关键字,我只是把它留空,用C#中的“ref”关键字替换“byRef”关键字,代码不起作用。
VB6代码:
Private Declare Function Foo Lib "Foo_Functions.dll" (ByVal a as String, ByVal b
as Long, ByVal c as String, ByVal d as String, ByVal e as String, ByVal f
as String, ByVal g as Long, ByVal h as String, ByVal i as String, ByRef j
as Long, ByRef k as Long) As
Integer
我的C#3.5翻译:
[Dllimkport("foo_functions.dll")] public static extern int foo(String a, long b,
string c, string d, string e, string f, long g, string h, stringbuilder i,
ref long j, ref long k);
请帮助,我已经花了一整天时间:p ....
最后,我使用自动项目转换器(从VB6到VB.NET 2008)将函数调用转换为VB.NET lib,并使用C#reference调用它。
感谢。
答案 0 :(得分:2)
如果在C#中用StringBuilder
替换它们,则可以修改byVal字符串。
另一种可能的解决方案是使用[MarshalAs(UnmanagedType.VBByRefStr)] ref string i
。
我在Visual Studio中使用了“升级Visual Basic 6代码...”工具,这导致了以下VB.NET代码:
Private Declare Function Foo Lib "Foo_Functions.dll" (ByVal a As String, _
ByVal b As Integer, ByVal c As String, ByVal d As String, ByVal e As _
String, ByVal f As String, ByVal g As Integer, ByVal h As String, ByVal i _
As String, ByRef j As Integer, ByRef k As Integer) As Short
请注意,VB6 Long
已转换为Integer
,而VB6 Integer
已转换为Short
。
然后我用反射器看看它在C#中的样子:
[DllImport("Foo_Functions.dll", CharSet=CharSet.Ansi, SetLastError=true, ExactSpelling=true)]
private static extern short Foo([MarshalAs(UnmanagedType.VBByRefStr)] ref
string a, int b, [MarshalAs(UnmanagedType.VBByRefStr)] ref string c,
[MarshalAs(UnmanagedType.VBByRefStr)] ref string d,
[MarshalAs(UnmanagedType.VBByRefStr)] ref string e,
[MarshalAs(UnmanagedType.VBByRefStr)] ref string f, int g,
[MarshalAs(UnmanagedType.VBByRefStr)] ref string h,
[MarshalAs(UnmanagedType.VBByRefStr)] ref string i, ref int j, ref int k);
这是VB6声明的确切翻译,应具有相同的行为。如果这仍然不起作用,那么也许你可以描述它究竟是如何工作的(非托管函数是否被调用,参数是垃圾,返回值是垃圾还是别的?)。
答案 1 :(得分:2)
查看www.pinvoke.net它显示了C#和VB.net示例。
答案 2 :(得分:1)
如果VB6声明包含ByVal s As String
的语句,则该参数将被编组为指向ANSI字符串的指针。我会尝试将DLLImport更改为[DllImport("Foo_Functions.dll", CharSet=CharSet.Ansi)]
对于输出参数,您需要使用StringBuilder s
并预先初始化StringBuilder,以保存输出。对于输入参数,您可以使用String s
你有DLL的C声明吗? Mabe在原始供应商的文档中,还是DLL源代码?如果是这样,有一个免费工具CLRInsideOut将该C声明转换为C#或VB.Net PInvoke代码。阅读更多on MSDN here。
免责声明:JaredPar应该真正获得此答案的任何代表点,因为他wrote some of the tool。