2010-01-04 71 views
1

我在VB6一些代碼,從DLL輸入功能,它使用BYVAL和BYREF關鍵字,我想這些代碼轉換成C#3.5。轉換從VB6 dllimport的爲C#3.5

  1. 是否會出現Unicode字符串編碼問題?

  2. 難道我聲明,是「按地址」的可變因素在VB6到「參考」中的C#代碼可變因素?

  3. 它將返回值輸入到由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庫,並使用C#參考調用它。

謝謝。如果你在C#與StringBuilder替換它們

+0

如果您在問題中包含VB6聲明導入的函數,可能會有所幫助。沒有任何代碼難以正確理解你正在嘗試做什麼。 – AnthonyWJones 2010-01-04 13:09:51

+0

您是否試圖從c#中調用win32 dll函數? – 2010-01-04 13:10:25

+0

@Stefan Steinegger:是 – 2010-01-04 13:29:01

回答

2

修改的BYVAL字符串應該工作。 另一種可能的解決方案是使用[MarshalAs(UnmanagedType.VBByRefStr)] ref string i

我用了 「升級Visual Basic 6的代碼......」 工具在Visual Studio中,這導致下面的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聲明的精確翻譯,並且應該有相同的行爲。如果這仍然不起作用,那麼也許你可以描述它到底有什麼不工作(非託管函數是否被調用,參數是垃圾,返回的值是垃圾,還有其他的東西?)。

+0

沒有幫助:/ – 2010-01-04 13:43:36

+0

嘗試使用VBByRefStr變體,並在需要時將CharSet = CharSet.Unicode添加到DllImport屬性。 – 2010-01-04 14:17:33

+0

@Pent Ploompuu:一直在那裏做,沒有幫助 – 2010-01-06 16:35:04

2

看一看www.pinvoke.net它顯示了C#和VB.net的例子。

+0

據我所知,這個工具只用於調用連接到Windows操作系統的dll,而不是自定義的。 – 2010-01-04 13:42:47

+1

是的你是對的。它有各種Windows API的dllImport調用示例。這些示例可以幫助您將VB轉換爲C#。 – 2010-01-04 14:12:53

+0

這些例子將幫助你將** VB.Net **轉換爲C#而不是** VB6 **。 OP需要將** VB6 **轉換爲C#。 – MarkJ 2011-05-26 15:13:31

1

如果VB6 Declare語句,其中包括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