在c#中使用DLLimport从c++ dll调用c#

本文关键字:c++ dll 调用 DLLimport | 更新日期: 2023-09-27 17:50:24

c++函数头在DLL中这两个函数获得一些关于我周围的wifi站的信息使用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#示例

[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适配器的名称,然后应用程序停止,给我不支持的例外,当手机试图执行命名为refreshBSSID()和getbssid()的其他两个函数,所以是什么问题?或者是否有其他解决方案来获取此信息(BSSID,SS等)?

在c#中使用DLLimport从c++ dll调用c#

c++默认使用调用者(Cdecl)调用约定。你的c++代码不会改变调用约定。默认情况下,你的c#代码(除非你改变它)将使用一个被调用约定(StdCall)。

虽然这可能不是你遇到的问题,但从技术上讲,它仍然是不正确的。即使你想解决当前的问题,你也很可能会因为调用约定而出现问题。

我猜你的c# BSSIDInfo结构与c++结构不匹配。为什么方法StrToByteArray当它所做的只是GetBytes给定的字符串…

,当移动设备尝试执行另外两个函数命名为refreshBSSID()和getbssid ()有问题吗?或者还有其他的获取此信息的解决方案

我以为我知道原因,再看一看,我错了。