来自 C++ 的 Pinvoke C# C# 中使用 DLLimport 的 dll

发布于 2024-11-01 21:44:37 字数 3347 浏览 1 评论 0原文

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# 应用程序上时 使用它们.exe 名为 Getadapters(..) 的第一个函数将第一个文本框中的适配器名称返回给我,然后应用程序停止并在移动设备尝试执行另外两个函数时给出不支持的异常,该函数名为refreshBSSID( ) 和 getBSSIDs() 那么问题是什么?或者是否有其他解决方案来获取此信息(BSSID,SS ..等)?

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

// (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
        }
    }
}

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 ? or is there another solution to get this information (BSSID ,SS ..etc) ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

巨坚强 2024-11-08 21:44:37

除非更改,C++ 默认情况下使用调用者 ( Cdecl ) 调用约定。您的 C++ 代码不会更改调用约定。默认情况下,您的 C# 代码(除非您更改它)将使用被调用者约定 (StdCall)。

虽然这可能不完全是您遇到的问题,但它在技术上仍然是不正确的。即使您要解决当前的问题,您也可能最终会因为调用约定而遇到问题。

我猜测您的 C# BSSIDInfo 结构与 C++ 结构不匹配。为什么 StrToByteArray 方法所做的只是对给定字符串进行 GetBytes...

当移动设备尝试执行
另外两个函数名为
freshBSSID() 和 getBSSIDs() 又怎样
有问题吗?或者还有另一个
获取此信息的解决方案

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

C++ by default unless changed uses a caller( Cdecl ) calling convention. Your C++ code does not change the calling convention. Your C# code by default ( unless you change it ) will use a callee convention ( 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. Why do the method StrToByteArray when all it does is GetBytes on the given string...

when the mobile tries to execute the
other two function that named as
refreshBSSID() and getBSSIDs() so what
is the problem ? or is there another
solution to get this information

I thought I knew the reason took another look and I was wrong.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文