C#调用非托管dll动态库返回值问题
函数原型:unsigned char* FindToken() 返回值是一个定长8字节的值我用C#如些调用:
[DllImport("GDHidUserCtrl.dll", EntryPoint = "FindToken")]
[return: MarshalAs(UnmanagedType.LPArray, SizeConst = 8)]
internal static extern byte[] FindToken();
public static byte[] getUsbKey()
{
return FindToken();
}
但运行时出现如下错误:
无法封送处理“return value”: 无效的托管/非托管类型组合。
说明: 执行当前 Web 请求期间,出现未处理的异常。请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息。
异常详细信息: System.Runtime.InteropServices.MarshalDirectiveException: 无法封送处理“return value”: 无效的托管/非托管类型组合。
源错误:
行 26: public static byte[] getUsbKey()
行 27: {
行 28: return FindToken();
行 29: }
行 30: }
源文件: e:\UsbKey\App_Code\UsbKeyClient.cs 行: 28
堆栈跟踪:
[MarshalDirectiveException: 无法封送处理“return value”: 无效的托管/非托管类型组合。]
UsbKeyClient.FindToken() +0
UsbKeyClient.getUsbKey() in e:\UsbKey\App_Code\UsbKeyClient.cs:28
testusbkey.Button1_Click(Object sender, EventArgs e) in e:\UsbKey\testusbkey.aspx.cs:20
System.Web.UI.WebControls.Button.OnClick(EventArgs e) +75
System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument) +98
System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +7
System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +11
System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +33
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +4919
跪求各位高手帮小弟解决此问题,好急人啊!!! --------------------编程问答-------------------- [DllImport("GDHidUserCtrl.dll", EntryPoint = "FindToken")]
[return: MarshalAs(UnmanagedType.LPArray, SizeConst = 8)]
internal static extern byte[] FindToken();
public static string getUsbKey()
{
return FindToken();
}
--------------------编程问答-------------------- [return: MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
--------------------编程问答-------------------- 对,char*-string,这里也要改 --------------------编程问答-------------------- qyl2008(),我用了你说的那个[return: MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] 还是出现错的问题,如下:
编译错误
说明: 在编译向该请求提供服务所需资源的过程中出现错误。请检查下列特定错误详细信息并适当地修改源代码。
编译器错误信息: CS0647: 发出“System.Runtime.InteropServices.MarshalAsAttribute”属性时出错 -- “指定的非托管类型只对字段有效。”
源错误:
行 22:
行 23: [DllImport("GDHidUserCtrl.dll", EntryPoint = "FindToken")]
行 24: [return: MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
行 25: internal static extern byte[] FindToken();
行 26: public static byte[] getUsbKey()
源文件: e:\UsbKey\App_Code\UsbKeyClient.cs 行: 24
--------------------编程问答-------------------- UnmanagedType.ByValArray只能在结构体里用的啊 --------------------编程问答-------------------- [DllImport("GDHidUserCtrl.dll", EntryPoint = "FindToken")]
internal static extern string FindToken();
// public static byte[] getUsbKey()
// {
// return FindToken();
// }
再试试这个
--------------------编程问答-------------------- [return: MarshalAs(UnmanagedType.LPArray, SizeConst = 8)]和
public static byte[] getUsbKey()
{
return FindToken();
}
都没必要要,只要将char*-string就行了,应该不会错的 --------------------编程问答-------------------- 根据错误的字面意思和经验,错误出在
[return: MarshalAs(UnmanagedType.LPArray, SizeConst = 8)]
参考这个
[DllImport("smgwapi.dll", EntryPoint = "CNGPSendSingle")]
unsafe public static extern int SendSingle(int nMsgType, int nNeedReport,
int nMsgLevel, string sServiceID, int nMsgFormat,
string sFeeType, int nFeeUserType, string sFeeCode,
string sValidTime, string sAtTime,
string sSrcTermID, string sChargeTermID, string sDestTermID,
int nMsgLen, string sMsgContent,
byte[] sMsgID, out IntPtr nErrorCode);
以下是SendSingle的c++原型
/********************************************************************
FunctionName: CNGPSendSingle
DESCRIPTION: Send a short message to single user,if succeed, message
id is filled in sMsgID.if fail, error code is filled in
nErrorCode.
Input: nMsgType: Msg subtype
nNeedReport:Need reply the status?0:no,1:yes
nMsgLevel:Message level:0:the lowest, 1:normal,
2:above normal 3:the highest
sServiceID:Server type
nMsgFormat:Message format
sFeeType:Fee type
sFeeUserType: fee user type
sFeeCode:Fee code
sValidTime:Valid time,format following smpp3.3
sAtTime:The time of sending,format following smpp3.3
sSrcTermId:Send user number
sChargeTermID:Paying User number
sDestTermID:Reveive Message number
nMsgLen:Message length
sMsgContent:Message Content
Output: sMsgID:If succeed, message id is filled in sMsgID
nErrorCode:If fail, error code is filled in nErrorCode
Return: 0=OK, 1=fail
History:
Date Version Modifier Activies
*******************************************************************/ --------------------编程问答-------------------- 我的错是错在返回值的类型错误啊 --------------------编程问答-------------------- [DllImport("CPPDLL.DLL", CallingConvention = CallingConvention.StdCall)]
public extern static IntPtr FindToken();
IntPtr bts = FindToken();
byte[] ret = new byte[8];
for (int i = 0; i < 8; ++i)
{
ret[i] = Marshal.ReadByte(bts);
bts = (IntPtr) (bts.ToInt32() + 1);
Console.WriteLine(ret[i]);
} --------------------编程问答-------------------- ls的办法不错,lz可以试试。可以做一点小小改进:
[DllImport("CPPDLL.DLL", CallingConvention = CallingConvention.StdCall)]
public extern static IntPtr FindToken();
IntPtr bts = FindToken();
byte[] ret = new byte[8];
Marshal.PtrToStructure(bts,ret); --------------------编程问答-------------------- 顶楼上 --------------------编程问答-------------------- 兄弟,你最后是怎么解决的啊,能把代码贴出来吗? --------------------编程问答-------------------- --------------------编程问答-------------------- 没有好的解决方案啊 --------------------编程问答-------------------- UP~~~ --------------------编程问答-------------------- 不涉及到机密的话,可以发一个试一下 --------------------编程问答-------------------- 求易做图
补充:.NET技术 , C#