Pinvoke C # из C ++ DLL с помощью DLLimport в C # - PullRequest
0 голосов
/ 14 апреля 2011

Заголовок функции C ++ в DLL - это две функции, позволяющие получить некоторую информацию о станциях Wi-Fi вокруг меня с помощью устройства win mobile 6.5, и мне нужно вызвать их, чтобы использовать их в коде C #

// (adapter names , pointer to destination buffer ,and the size , returned structs)
bool __declspec(dllexport) GetBBSIDs(LPWSTR pAdapter, struct BSSIDInfo *pDest, DWORD &dwBufSizeBytes, DWORD &dwReturnedItems);
bool __declspec(dllexport) RefreshBSSIDs(LPWSTR pAdapter);
bool __declspec(dllexport) GetAdapters(LPWSTR pDest, DWORD &dwBufSizeBytes);

C # sample

[DllImport(@"\Storage Card\Work\Beaad.dll", EntryPoint = "GetAdapters", SetLastError = true)]
public static extern bool getAdapters([MarshalAs(UnmanagedType.LPWStr)] String buf, ref UInt32 dwBufSizeBytes);

[DllImport(@"\Storage Card\Work\Beaad.dll", EntryPoint = "RefreshBSSIDs", SetLastError = true)]
public static extern bool refreshBSSIDs([MarshalAs(UnmanagedType.LPWStr)]String buf);

[DllImport(@"\Storage Card\Work\Beaad.dll", EntryPoint = "GetBBSIDs", SetLastError = true)]
public static extern bool getBBSIDs([MarshalAs(UnmanagedType.LPWStr)]String buf,BSSIDInfo [] nfo, ref UInt32 dwBufSizeBytes, ref UInt32 dwReturnedItems);

[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Auto)]
public struct BSSIDInfo
{
    public byte[] BSSID; //mac
    public char[] SSID;

    public BSSIDInfo(byte[]bs,char[] ss)
    {
        this.RSSI = 0;
        this.Infastructure = 0;
        this.Channel = 0;
        this.Auth = 0;
        bs = new byte[6];
        ss = new char[32];
        BSSID = bs;
        SSID = ss;
    }
    public int RSSI;
    public int Channel;
    public int Infastructure;
    public int Auth;
}

public static byte[] StrToByteArray(string str)
{
    System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
    return encoding.GetBytes(str);
}
public static char[] c = new char[1024];
string buf = new string(c);
public void button1_Click(object sender, EventArgs e)
{
    BSSIDInfo[] nfo = new BSSIDInfo[128];
    byte[] bytee=StrToByteArray(buf);
    UInt32 dwsize= new UInt32();
    UInt32 dwTmp = new UInt32();
    UInt32 dwCount = new UInt32();
    dwTmp = Convert.ToUInt32(Marshal.SizeOf(typeof(BSSIDInfo)) * nfo.Length);
    dwCount =0;
    dwsize=Convert.ToUInt32(bytee.Length);
    if (false == getAdapters(buf,ref dwsize) || dwsize == 0)
    {
        label1.Text = "no adabters";
    }
    else
    {
        String [] strList=new String[15];    
        if (buf.Contains(',') == false)// one adapter
        {
            textBox1.Text = buf;
        }
        else
        {
            strList = buf.Split(',');
            for (int i = 0; i < strList.Length; i++)
            {
                textBox1.Text+= strList[i]+Environment.NewLine;
            }
        }
        if (refreshBSSIDs(buf) && getBBSIDs(buf, nfo, ref dwTmp, ref dwCount) && dwCount > 0)
        {
            //refreshBSSIDs(buf) &&
            for (int i = 0; i < dwCount; i++)
            {
                textBox2.Text += nfo.GetValue(i).ToString() + Environment.NewLine;
            }
        }
        else
        {
            //make another thing
        }
    }
}

и когда я ставлю эту DLL на мобильный и C # app.exe, первая функция с именем Getadapters (..) возвращает мне имя адаптера в первом текстовом поле1, затем приложение останавливаетсяи дать мне неподдерживаемое исключение, когда мобильное устройство пытается выполнить две другие функции, которые названы как refreshBSSID () и getBSSIDs (), так в чем же проблема?или есть другое решение для получения этой информации (BSSID, SS ..etc)?

1 Ответ

0 голосов
/ 14 апреля 2011

C ++ по умолчанию, если не изменено, используется соглашение о вызовах вызывающей стороны (Cdecl).Ваш код C ++ не меняет соглашение о вызовах.Ваш код C # по умолчанию (если вы его не измените) будет использовать соглашение вызываемого абонента (StdCall).

Хотя это может быть не совсем той проблемой, ваша техническая неверность по-прежнему неверна.Даже если вы решите свою текущую проблему, вы, скорее всего, столкнетесь с проблемой из-за соглашения о вызовах.

Я собираюсь предположить, что ваша структура C # BSSIDInfo не соответствует структуре C ++.Почему метод StrToByteArray, когда все, что он делает, это GetBytes для данной строки ...

, когда мобильная станция пытается выполнить две другие функции, которые называются refreshBSSID () и getBSSIDs (), так чтоэта проблема ?или есть другое решение, чтобы получить эту информацию

Я думал, что знал, что причина взяла другой взгляд, и я был неправ.

...