将dllimport从vb6转换为c#3.5

时间:2010-01-04 13:05:14

标签: c# vb6 interop dllimport

我在VB6中有一些代码从dll导入函数,它使用byVal和byRef关键字,我想将该代码转换为C#3.5。

  1. 字符串的unicode编码是否会出现问题?

  2. 我是否将vb6中“byRef”的变量声明为C#代码中的“ref”变量?

  3. 接收返回值被输入VB6代码发送的字符串中作为“byVal”参数,如果你想允许,你应该如何发送东西“byRef”编辑字符串的功能?这个概念是否仍适用于我的C#代码?

  4. 我尝试从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调用它。

    感谢。

3 个答案:

答案 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