2010-11-22 3 views
1

Я работаю с некоторым оборудованием, имеющим DLL. Я считаю, что у него есть два метода вызова функциональности (от использования приложения-шпиона DLL).VB6/C++ WINAPI to C#

В настоящее время она работает в VB6 с помощью

Public Type Versions 
    Pname As Long 
    Manuf As Long 
    VMajor As Long 
    VMinor As Long 
    VState As Long 
End Type 

Public Declare Function FLASH_GetVersion Lib "C:\flash_cntrl.dll" (ByVal fxc_Versions As Long) As Integer 

Dim vVers As Versions 
Dim strProdName As String 
Dim strManuf As String 

strProdName = "                        " 
strManuf = "                        " 

vVers.Manuf = StrPtr(strManuf) 
vVers.Pname = StrPtr(strProdName) 

iReturn = FLASH_GetVersion(VarPtr(vVers)) 

Меня «принудительный», чтобы перейти к C# 2008/2010, чтобы иметь возможность использовать некоторые другие аппаратные средства, которые не поддерживаются в VB6.

Итак, я пытаюсь использовать приведенное выше и работает в ошибке AccessViolationException. Мне «повезло» достаточно, чтобы иметь заголовочный файл C++ с определениями WinAPI, но он все еще борется. Любая помощь приветствуется.

typedef struct { 
LPWSTR productname; 
LPWSTR manufacturer; 
unsigned Vers_Major; 
unsigned Vers_Minor; 
unsigned Vers_State;  // = 0 released, > 0 internal use only 
} FLASH_INFO; 

int WINAPI FLASH_GetVersion (FLASH_INFO *fxc_Version); 

Мой C# до сих пор

static class NativeMethods 
{ 
    [DllImport("C:\\flash_cntrl.dll")] 
    public static extern short FLASH_GetVersion(FLASH_INFO vVers); 
} 

public class FLASH_INFO 
{ 
    public string productname; 
    public string manufacturer; 
    public int Vers_Major; 
    public int Vers_Minor; 
    public int Vers_State; 
} 

     FLASH_INFO vers = new FLASH_INFO(); 

     string strManuf = "        "; 
     string strProdName = "        "; 

     vers.productname = strProdName; 
     vers.manufacturer = strManuf; 
     vers.Vers_Major = 0; 
     vers.Vers_Minor = 0; 
     vers.Vers_State = 0; 

     short sRet = NativeMethods.FLASH_GetVersion(vers); 

     Console.WriteLine("{0}|{1}", "sRet", sRet.ToString()); 

Это, вероятно, что-то простое, но я относительно новым для языка C# (сделано некоторое настольное программирование и Silverlight только).

Вы заранее заблаговременно

ответ

0

По умолчанию маршалинг для строк является 8-разрядным символом, однако LPWSTR является строкой Unicode. Неверный тип возврата. Исправление:

[DllImport("C:\\flash_cntrl.dll")] 
public static extern int FLASH_GetVersion(ref FLASH_INFO vVers); 

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode) 
public struct FLASH_INFO 
{ 
    public string productname; 
    public string manufacturer; 
    public int Vers_Major; 
    public int Vers_Minor; 
    public int Vers_State; 
} 
+0

Отдайте ему ход. Спасибо :) –

+0

Легенда! Большое спасибо! –

+0

Я не могу голосовать, поскольку у меня нет репутации, но вы этого заслуживаете! –

0

string strManuf = ""; string strProdName = "";

vers.productname = strProdName; 
vers.manufacturer = strManuf; 

проблема в этих строках. их тип структуры C++ - это LPWSTR, который преобразуется в IntPtr в .net, который является указателем на объект.

+0

Я понимаю это. Итак, какая-нибудь идея, как я обойду это? –

+0

Да, вы могли бы задать этот вопрос без отрицательного бессмысленного голосования. решите его на своего собеседника. –

+0

Я не отрицал вас, насколько я знаю. Я даже не вошел в систему. Но в любом случае спасибо! :) –