请大家帮我结局一个c#调用win32 api dll的问题

huangcaibing 2008-01-27 06:48:40
C定义如下:
BOOL effnEDClientCheckPointInfoByTime(
efSTReadRtInfoRequest*pReqBuffer,//
efSTReadRtInfoResponse * pResBuffer,//
unsigned long Count //
);
结构如下:
#define EFMI_POINTNAMELENGTH 48
#define EFMI_POINTCOMMLENGTH EFMI_POINTNAMELENGTH

//查询实时记录请求包结构

typedef struct defefSTReadRtInfoRequest
{
long time; //
char pointName[EFMI_POINTNAMELENGTH+1];//EFMI_POINTNAMELENGTH+1;
char ednaServ[EFMI_POINTCOMMLENGTH+1]; //
}efSTReadRtInfoRequest;


//查询实时记录回复包结构

typedef struct defefSTReadRtResponse
{
double value;
long time;
unsigned short status;//
char pointName[EFMI_POINTNAMELENGTH+1];//
}efSTReadRtInfoResponse;


/////////////////////////////
//c#的程序如下:
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Runtime.InteropServices;

namespace ednaClient
{
/// <summary>
/// Form1 的摘要说明。
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.Button button1;
private System.Windows.Forms.TextBox textBox1;
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.Container components = null;




public Form1()
{
//
// Windows 窗体设计器支持所必需的
//
InitializeComponent();

//
// TODO: 在 InitializeComponent 调用后添加任何构造函数代码
//
}

/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

#region Windows 窗体设计器生成的代码
/// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
/// 此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Button();
this.textBox1 = new System.Windows.Forms.TextBox();
this.SuspendLayout();
//
// button1
//
this.button1.Location = new System.Drawing.Point(100, 76);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(80, 24);
this.button1.TabIndex = 0;
this.button1.Text = "button1";
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// textBox1
//
this.textBox1.Location = new System.Drawing.Point(100, 168);
this.textBox1.Name = "textBox1";
this.textBox1.Size = new System.Drawing.Size(152, 21);
this.textBox1.TabIndex = 1;
this.textBox1.Text = "textBox1";
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
this.ClientSize = new System.Drawing.Size(416, 318);
this.Controls.Add(this.textBox1);
this.Controls.Add(this.button1);
this.Name = "Form1";
this.Text = "Form1";
this.Load += new System.EventHandler(this.Form1_Load);
this.ResumeLayout(false);

}
#endregion

/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}

private void Form1_Load(object sender, System.EventArgs e)
{

}

[StructLayout(LayoutKind.Sequential,CharSet= CharSet.Unicode)]
public struct defefSTReadRtInfoRequest
{
public Int32 time;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 48)]
public string pointName;//
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 48)]
public string ednaServ;//


}

//****************************************************************
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct defefSTReadRtResponse
{
public double value;
public Int32 time;
public UInt16 status;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 48)]
public string pointName;//

};

[DllImport(@"efEDClient.dll", EntryPoint = "effnEDClientInit", CharSet = CharSet.Unicode)]
public static extern bool effnEDClientInit();

[DllImport(@"efEDClient.dll", EntryPoint = "effnEDClientCheckPointInfoByTimeEx", CharSet = CharSet.Unicode)]
public static extern bool effnEDClientCheckPointInfoByTimeEx(ref defefSTReadRtInfoRequest requestBuffer, out defefSTReadRtResponse responseBuffer, UInt32 count);

private void button1_Click(object sender, System.EventArgs e)
{
if(!effnEDClientInit())
{
textBox1.Text="网络不通,初始化参数可能有问题!";
return;
}
string[] p = new string[4] { "GWDCS01.UI_PUSH.LBACT103", "GDHYSSIS.U31_RTS.1TURC:J15_01.PNT", "GDHYSSIS.U31_RTS.1TURC:J15_04.PNT", "GDHYSSIS.U31_RTS.1TURC:J15_11.PNT"};
uint nCount=2;
try
{
for(int i = 0; i < nCount; i++)//显示输出数据
{
defefSTReadRtInfoRequest req = new defefSTReadRtInfoRequest();
System.Text.UnicodeEncoding converter = new System.Text.UnicodeEncoding();

string arrP, arrServ;
arrP = p[i];
arrServ = "GWDCS01.UI_PUSH";
req.pointName = arrP.PadRight(48);
req.ednaServ = arrServ.PadRight(48);
// Array.Copy(converter.GetBytes(arrP), 0, req.pointName,0, converter.GetBytes(arrP).Length);
// Array.Copy(converter.GetBytes(arrServ), 0, req.ednaServ,0, converter.GetBytes(arrServ).Length);
req.time = 0;

defefSTReadRtResponse iResp = new defefSTReadRtResponse();
iResp.pointName= new string(' ',48);

if (effnEDClientCheckPointInfoByTimeEx(ref req, out iResp, nCount))
{
Console.WriteLine( "值:" + iResp.value.ToString() + "---" + iResp.status.ToString() + "time:" + iResp.time.ToString());
}
}
}
catch(Exception ex)
{
Console.Write(ex.Message);
}
}

}
}

返回的结果是错误的,我想肯定是传入的参数有问题
...全文
179 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
唐文-1983 2010-10-22
  • 打赏
  • 举报
回复
public partial class NativeConstants {

/// EFMI_POINTNAMELENGTH -> 48
public const int EFMI_POINTNAMELENGTH = 48;

/// EFMI_POINTCOMMLENGTH -> EFMI_POINTNAMELENGTH
public const int EFMI_POINTCOMMLENGTH = NativeConstants.EFMI_POINTNAMELENGTH;
}

[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential, CharSet=System.Runtime.InteropServices.CharSet.Ansi)]
public struct defefSTReadRtInfoRequest {

/// int
public int time;

/// char[49]
[System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst=49)]
public string pointName;

/// char[49]
[System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst=49)]
public string ednaServ;
}

[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential, CharSet=System.Runtime.InteropServices.CharSet.Ansi)]
public struct defefSTReadRtResponse {

/// double
public double value;

/// int
public int time;

/// unsigned short
public ushort status;

/// char[49]
[System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst=49)]
public string pointName;
}

public partial class NativeMethods {

/// Return Type: BOOL->int
///pReqBuffer: efSTReadRtInfoRequest*
///pResBuffer: efSTReadRtInfoResponse*
///Count: unsigned int
[System.Runtime.InteropServices.DllImportAttribute("<Unknown>", EntryPoint="effnEDClientCheckPointInfoByTime")]
[return: System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.Bool)]
public static extern bool effnEDClientCheckPointInfoByTime(ref defefSTReadRtInfoRequest pReqBuffer, ref defefSTReadRtResponse pResBuffer, uint Count) ;

}
Q_282898034 2008-02-24
  • 打赏
  • 举报
回复
强贴,关注!
huangcaibing 2008-02-24
  • 打赏
  • 举报
回复
现在有另外一个问题,输出的时间为long,如何转换成c#中的时间呢?

[DllImport("efEDClient.dll", EntryPoint = "effnEDClientCheckPointInfoByTimeEx", CharSet = CharSet.Ansi)]
public static extern bool effnEDClientCheckPointInfoByTimeEx(ref defefSTReadRtInfoRequest requestBuffer, out defefSTReadRtResponse ptr, ushort count);


//在此调用
effnEDClientCheckPointInfoByTimeEx(ref req, out iResp, (ushort)nCount));

//返回的iResp
//其中iResp.time为long类型,我怎么把它还原成c#中的时间呢。
6288995410144995201
我数了一下,有19位,
而System.DateTime.Now.Ticks的值:只有18位
633394663878829296

c++中是怎么存的时间格式,需要如何转换?
真相重于对错 2008-01-28
  • 打赏
  • 举报
回复
第二个是数组,用 System.IntPtr,在.net里定义数组, Marshal 有获取 数组的地址 的函数
huangcaibing 2008-01-28
  • 打赏
  • 举报
回复
我试试看,我还是不懂啊,能不能帮我说具体一点啊?
rangeon 2008-01-28
  • 打赏
  • 举报
回复
帮顶
huangcaibing 2008-01-27
  • 打赏
  • 举报
回复
我这里有个VC调用这个dll的例子, 在c#中我不知道怎么用,VC我也不懂
// RtTest.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "windows.h"
#include "efdef.h"
#include "iostream.h"

void LookRtData()
{
//查询数据

HINSTANCE hDLL;
hDLL=LoadLibrary("efEDClient.dll");
typedef int(*pMy)();
pMy InitNetWork=(pMy)GetProcAddress(hDLL,"effnEDClientInit");//有连接的函数访问数据库;
if(InitNetWork())
{
CTime stTime=CTime::GetCurrentTime();
while(1)
{
// printf("请输入点名\n");
int nCount=10;//查询点的数量
int n=sizeof(efSTReadRtInfoRequest);
unsigned long length=nCount*sizeof(efSTReadRtInfoRequest);
efSTReadRtInfoRequest *req=new efSTReadRtInfoRequest[nCount];//开辟存储空间用于存储发送查询请求
memset(req,0,sizeof(efSTReadRtInfoRequest)*nCount);//清0e
efSTReadRtInfoResponse *resp=new efSTReadRtInfoResponse[nCount];//开辟存储空间用于存储接受数据库回复信息
memset(resp,0,sizeof(efSTReadRtInfoResponse)*nCount);//清0
for(int i=0;i<nCount;i++)
{

// if(i==5)
req[i].time=0;
//strcpy(req[i].pointName,"TEST.PUSHSERV.1BHVE121");
sprintf(req[i].pointName,"TEST.PUSHSERV.TEST%d",i+10);

}
//调用动态连接库查询数据,若成功则返回TRUE,失败返回FALSE
typedef BOOL(*pMy)(efSTReadRtInfoRequest*,efSTReadRtInfoResponse*,unsigned long );
pMy p=(pMy)GetProcAddress(hDLL,"effnEDClientCheckPointInfoByTimeEx");
if(p(req,resp,nCount))
{
for(int i=0;i<nCount;i++)//显示输出数据
{
printf("%s,%f,%d,%d\n",resp[i].pointName,resp[i].value,resp[i].status,resp[i].time);
}
// printf("%s\n", (char*)resp);
}
else
{
printf("连接失败\n");
continue;
}
delete[] req;//释放空间
delete[] resp;
HANDLE hEvent=CreateEvent(NULL,FALSE,FALSE,NULL);
WaitForSingleObject(hEvent,1000);
}
}
else
printf("连接失败");
// Sleep(1000);
FreeLibrary(hDLL);

// return 0;
}

int main(int argc, char* argv[])
{

DWORD dwThreadId;
HANDLE hThread;
int i=0;
while(i<1)
{
hThread = CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE)LookRtData,
(LPVOID)NULL, 0, &dwThreadId);
if ( hThread )
CloseHandle(hThread);
HANDLE hEvent=CreateEvent(NULL,FALSE,FALSE,NULL);
WaitForSingleObject(hEvent,1000);
i++;
}
HANDLE hEvent=CreateEvent(NULL,FALSE,FALSE,NULL);
WaitForSingleObject(hEvent,INFINITE);

return 0;
}
huangcaibing 2008-01-27
  • 打赏
  • 举报
回复
BOOL effnEDClientCheckPointInfoByTime
(
efSTReadRtInfoRequest* pReqBuffer,//这里是是输入,C++要求这个是指针
efSTReadRtInfoResponse* pResBuffer,//这里是输出,C++要求是个指针
unsigned long Count //
);

谢谢
真相重于对错 2008-01-27
  • 打赏
  • 举报
回复
首先你要知道这个函数参数里的字符编码格式
其次
c++函数 需要调用者明白它自己的具体语义,有时虽然是同一句代码,但 c++ 不同的操作,调用方式是不一样的
你这个函数里

BOOL effnEDClientCheckPointInfoByTime(
efSTReadRtInfoRequest * pReqBuffer,// 这里是输出 或者是输入,还有这里C++要求是个指针还是数组
efSTReadRtInfoResponse* pResBuffer,// 这里是输出 或者是输入,还有这里C++要求是个指针还是数组

unsigned long Count //
);

110,533

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧