簡體   English   中英

使用C#中的DLLimport從C ++ dll調用Pinvoke C#

[英]Pinvoke C# from C++ dll using DLLimport in C#

DLL中的C ++函數標頭,這兩個函數使用Win Mobile 6.5設備獲取有關我周圍的wifi站的一些信息,我需要調用它們才能在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#示例

[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(..)的函數在第一個textbox1中向我返回了適配器的名稱,然后該應用程序停止了,當mobile嘗試執行另外兩個名為refreshBSSID()和getBSSIDs()的函數,這是什么問題? 還是有其他解決方案來獲取此信息(BSSID,SS ..etc)?

除非更改,否則C ++默認情況下使用調用方(Cdecl)調用約定。 您的C ++代碼不會更改調用約定。 默認情況下,您的C#代碼(除非您進行更改)將使用被調用者約定(StdCall)。

雖然這可能不完全是問題,但從技術上講,您仍然遇到問題。 即使您要解決當前的問題,由於調用約定,您最終也可能會遇到問題。

我猜你的C#BSSIDInfo結構與C ++結構不匹配。 為什么方法StrToByteArray的全部作用是給定字符串上的GetBytes ...

當移動設備嘗試執行名為refreshBSSID()和getBSSIDs()的其他兩個函數時,這是什么問題? 還是有其他解決方案來獲取此信息

我以為我知道原因又來了,我錯了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM