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
// (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) ?
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.
精彩评论