English 中文(简体)
Converting dllimport from vb6 to c# 3.5
原标题:

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.

问题回答

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?).

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

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.





相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

热门标签