在c#中调用DELPH编写的DLL的函数时出现未将对象引用到实例的错误: delphi编写的dll中函数声明:function DeliverfromEsm(var Smtype, Content,Caller:pchar):integer;


Content:短信内容或报告(若Smtype为即时消息或离线消息,则Content表示短信内容;否则,Content表示返回的状态报告情况);   Content表示返回的状态报告Report结构:     DWORD TaskID; //客户端序列号 TaskID     DWORD MsgID; //客户端序列号 MsgID     char UserNumber[22]; //接收手机号     unsigned char state; //状态     unsigned char ErrCode; //错误代码 我在c#中声明: [DllImport("EsmApi.dll",CharSet  =  CharSet.Ansi,CallingConvention  =  CallingConvention.StdCall)] static extern int DeliverfromEsm(ref string smtype,ref string content,ref string caller); 调用: string smtype=”"; string content=”"; string caller=”"; int reportval=DeliverfromEsm( ref smtype,ref content,ref caller); 出现未将对象引用到实例的错误


以下是解决办法:


声明:


[DllImport("EsmApi.dll",CharSet   =   CharSet.Ansi,CallingConvention   =   CallingConvention.StdCall)]   static extern int DeliverfromEsm(StringBuilder Smtype, IntPtr Content,StringBuilder Caller);//接收短信和report


[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Ansi,Pack=1)]   public struct Report   {    public int TaskID;//4byte    public int MsgID;    [MarshalAs(UnmanagedType.ByValTStr,SizeConst=22)]public string UserNumber;    public byte state;//1byte    public byte ErrCode;   }


程序中处理:


StringBuilder   smtype=   new   StringBuilder(256);//Init   buffer         


    int size = Marshal.SizeOf(typeof(Report));     IntPtr content=Marshal.AllocHGlobal(size);//分配32bytes     StringBuilder   caller=   new   StringBuilder(256);//Init   buffer     int reportval=DeliverfromEsm(  smtype,content, caller);


//字符串时


string smscontent=Marshal.PtrToStringAnsi(content);


//结构体时


Report content1=(Report)Marshal.PtrToStructure(content,typeof(Report));


Marshal.FreeHGlobal(content);//释放


参考了网上的一段代码:


[StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]    public struct VideoCompressorInfo    {        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]        public string szName;        public Int32 dwHandle;    }        [DllImport("DSStream.dll")]        public extern static int DSStream_EnumVideoCompressor(IntPtr pInfo, ref int piVidCompNum);             int num = 0;            DSStream_EnumVideoCompressor(IntPtr.Zero, ref num);            int size = Marshal.SizeOf(typeof(VideoCompressorInfo));            IntPtr structPtr = Marshal.AllocHGlobal(size * num);            DSStream_EnumVideoCompressor(structPtr, ref num);            VideoCompressorInfo[] infos = new VideoCompressorInfo[num];            for (int i = 0; i < num; ++i)            {                infos[i] = (VideoCompressorInfo)Marshal.PtrToStructure((IntPtr)((int)structPtr + i * size), typeof(VideoCompressorInfo));            }            Marshal.FreeHGlobal(structPtr);


最近在的项目有涉及到使用摄像头的功能,摄像机就是市面上普通的摄像机,摄像机连接在一款视频监控卡上(天敏SDK2000),可是监控卡提供的动态链接库只有VC++的例子,有些地方看不明白,高手指教,解决了加分,监控卡提供的主要函数如下:
1.HRESULT DSStream_Initialize()
  初始化COM接口及一些参数。这是开始使用动态库的第一个函数,未初始化之前,任何其他函数的调用均无效。
2.HRESULT DSStream_ConnectDevice(int iCardID, BOOL bOverlay, HWND hParentWnd = NULL)
  连接视频捕捉卡。只有连接后,才能对卡进行其他操作。
  iCardID:想要连接的卡号,以0为基数。
  bOverlay:是否使用 Overlay 模式。TRUE-使用,FALSE-不使用。使用 Overlay 时,显示速度快、占用CPU资源极少,但是不能快照、录像、显示Logo等。
  hParentWnd:指定视频图像的父窗口,图像将显示在 hParentWnd 窗口中。也可用DSStream_SetOwnerWnd来指定父窗口。
3.HRESULT DSStream_SetOwnerWnd(int iCardID, HWND hParentWnd)
  设置视频显示窗口的父窗口,视频图像将在这个窗口中显示。
  hParentWnd:父窗口的句柄。
4.HRESULT DSStream_SetWindowPos(int iCardID, RECT rc)
设置视频图像在父窗口中的位置。如果所设位置的宽、高与视频图像实际的宽、高不等,视频图像将被缩放。视频图像的实际宽、高可通过调用DSStream_GetVideoInfo得到。
rc:视频图像在父窗口中的位置。


只写了其中的四个函数,高手请给个思路,或者解决下面的几个疑问也好:
1.HRESULT 是一种类型还是什么别的?
2. SetWindowPos(int iCardID, RECT rc) 其中RECT rc 应该怎么定义
3.我用下面语句调用,有什么不对的地方?
[DllImport("DSStream")]
        private static extern void DSStream_Initialize();
        [DllImport("DSStream")]
        private static extern void DSStream_Uninitialize();
        [DllImport("DSStream")]
        private static extern void DSStream_ConnectDevice(int iCardID, bool bOverlay, Panel hParentWnd);
        [DllImport("DSStream")]
        private static extern void DSStream_SetOwnerWnd(int iCardID, Panel hParentWnd);


DSStream_Initialize();
DSStream_SetOwnerWnd( 0, label1.Handle );


CSRect rc = new CSRect();
            rc.left = 0;
            rc.top = 0;
            rc.right = lablel.width;
            rc.bottom = label.heigth;
DSStream_SetWindowPos(0, rc);


DSStream_ConnectDevice(0, true, label1.Handle);


 我干脆把OCX弄进去了··

历史博文

标签:,
十一月 15, 2009 at 2:04 上午 by yippee 27 次
Category: Info
Tags: ,