将 dllimport 从 vb6 转换为 c# 3.5

发布于 2024-08-17 09:48:34 字数 1018 浏览 7 评论 0原文

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

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

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

  3. 返回值被输入到由 VB6 代码作为“byVal”参数发送的字符串中,这是如何工作的,如果您想让函数编辑字符串?这个概念仍然适用于我的 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),并使用 C# 引用调用它。

谢谢。

I have some code in VB6 which imports a function from a dll, it uses the byVal and byRef keywords, I want to convert that code into C# 3.5.

  1. Is there going to be a problem with unicode encoding of the strings?

  2. Do I declare the varibles that are "byRef" in vb6 into "ref" varibles in the C# code?

  3. It seams that return value is entered into a string send by the VB6 code as a "byVal" parameter, how does that work, aren't you supposed to send stuff "byRef", if you want to allow the function to edit the string? Is this concept still going to work with my C# code?

I tryed coping the function declaration from VB6, the parameter types are just int's, long's and string. Where there was a "byVal" keyword I just left it empty and replaced "byRef" keywords with the "ref" keyword in C# and the code dosn't work.

The VB6 Code:

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

My C# 3.5 Translation:

[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);

Please help, I'v already spent a whole day on this :p....

In the end I converted the function call to a VB.NET lib, using the automatic project converter (from VB6 to VB.NET 2008), and called it using C# reference.

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

始终不够爱げ你 2024-08-24 09:48:34

如果您将可修改的 byVal 字符串替换为 C# 中的 StringBuilder,则它们应该可以工作。
另一种可能的解决方案是使用[MarshalAs(UnmanagementType.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
然后我使用 Reflector 来查看它在 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 声明的精确翻译,并且应该具有相同的行为。如果这仍然不起作用,那么也许您可以描述它到底是如何不起作用的(非托管函数是否被调用,参数是垃圾,返回值是垃圾,还是其他什么?)。

Modifiable byVal strings should work if you replace them with StringBuilder in C#.
Another possible solution is to use [MarshalAs(UnmanagedType.VBByRefStr)] ref string i.

I used the "Upgrade Visual Basic 6 code..." tool in Visual Studio and this resulted in the following VB.NET code:

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

Note that VB6 Long was converted to Integer and VB6 Integer was converted to Short.
I then used reflector to see how it should look like in 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);

This is the exact translation of the VB6 declaration and should have the same behaviour. If this still doesn't work then perhaps you could describe how exactly it doesn't work (does the unmanaged function ever get called, are the arguments garbage, are the returned values garbage, something else?).

二智少女猫性小仙女 2024-08-24 09:48:34

看看 www.pinvoke.net 它显示了 C# 和 VB.net 示例。

have a look at www.pinvoke.net It shows C# and VB.net examples.

滿滿的愛 2024-08-24 09:48:34

如果 VB6 Declare 语句包含 ByVal s As String,则该参数将被编组为指向 ANSI 字符串的指针。我会尝试将 DLLImport 更改为 [DllImport("Foo_Functions.dll", CharSet=CharSet.Ansi)]

对于输出参数,您需要使用 StringBuilder s 并且预初始化 StringBuilder 足够大以容纳输出。对于输入参数,您可以使用 String s

您有 DLL 的 C 声明吗?也许在原始供应商的文档中,或者 DLL 源代码中?如果是这样,有一个免费工具 CLRInsideOut 会将 C 声明转换为 C# 或 VB.Net PInvoke 代码。请在 MSDN 上阅读更多信息

免责声明:JaredPar 应该真正获得此答案的任何代表点,因为他 编写了一些工具

If a VB6 Declare statement which includes ByVal s As String, that parameter will be marshalled as a pointer to an ANSI string. I would try changing the DLLImport to [DllImport("Foo_Functions.dll", CharSet=CharSet.Ansi)]

For output parameters, you will need to use StringBuilder s and also preinitialise the StringBuilder large enough to hold the output. For input parameters, you can use String s

Do you have a C declaration for the DLL? Mabe in the original vendor's documentation, or the DLL source code? If so, there is a free tool CLRInsideOut that will convert that C declaration to C# or VB.Net PInvoke code. Read more on MSDN here.

Disclaimer: JaredPar should really get any rep points for this answer since he wrote some of the tool.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文