简体   繁体   English

使用C#中的DLLimport从C ++ dll调用Pinvoke C#

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

C++ Function header in DLL this two function to get some information about the wifi stations around me using win mobile 6.5 device and i need to invoke them to use them in C# code 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# sample 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
        }
    }
}

and when i put this dll on the mobile and the C# app.exe the first function that named as Getadapters(..) return to me the name of the adapter in the first textbox1 then the app stopped and give me not supported exception when the mobile tries to execute the other two function that named as refreshBSSID() and getBSSIDs() so what is the problem ? 当我将此dll放在手机和C#app.exe上时,第一个名为Getadapters(..)的函数在第一个textbox1中向我返回了适配器的名称,然后该应用程序停止了,当mobile尝试执行另外两个名为refreshBSSID()和getBSSIDs()的函数,这是什么问题? or is there another solution to get this information (BSSID ,SS ..etc) ? 还是有其他解决方案来获取此信息(BSSID,SS ..etc)?

C++ by default unless changed uses a caller( Cdecl ) calling convention. 除非更改,否则C ++默认情况下使用调用方(Cdecl)调用约定。 Your C++ code does not change the calling convention. 您的C ++代码不会更改调用约定。 Your C# code by default ( unless you change it ) will use a callee convention ( StdCall ). 默认情况下,您的C#代码(除非您进行更改)将使用被调用者约定(StdCall)。

While this might not be exactly the problem your having it still is technically incorrect. 虽然这可能不完全是问题,但从技术上讲,您仍然遇到问题。 Even if you were to fix your current problem you likely will end up having a problem because of the calling convention. 即使您要解决当前的问题,由于调用约定,您最终也可能会遇到问题。

I am going to guess your C# BSSIDInfo structure does not match the C++ structure. 我猜你的C#BSSIDInfo结构与C ++结构不匹配。 Why do the method StrToByteArray when all it does is GetBytes on the given string... 为什么方法StrToByteArray的全部作用是给定字符串上的GetBytes ...

when the mobile tries to execute the other two function that named as refreshBSSID() and getBSSIDs() so what is the problem ? 当移动设备尝试执行名为refreshBSSID()和getBSSIDs()的其他两个函数时,这是什么问题? or is there another solution to get this information 还是有其他解决方案来获取此信息

I thought I knew the reason took another look and I was wrong. 我以为我知道原因又来了,我错了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM