C 呼叫C 函式來與串列埠通訊

2021-06-07 01:14:34 字數 4145 閱讀 3321

前些日子幫朋友寫個小軟體,要求用c#來實現主程式,主要的功能是與一些通訊裝置打交道,當然就是通過串列埠了,以十進位制傳送和讀取串列埠

的資料,考慮到c#呼叫api並沒有c++來得方便,因此,我用c++封裝了乙個讀寫串列埠的dll,只提供乙個函式供外部呼叫,這樣的好處在於,c#

只要呼叫這個函式傳送完資料後,函式立即就能獲得串列埠返回的資料。另乙個好處在於,一些不熟悉c++的朋友,也能夠直接通過這個dll來對

串列埠做一些操作。

雜話就不多講了,直接貼這個讀寫串列埠的dll**:

一. c++部分:

1)標頭檔案:

// serialportsync.h: inte***ce for the cserialportsync class.

////

#if !defined(afx_serialportsync_h__7fc698bb_bf4d_449e_8de9_62b8876187cf__included_)

#define afx_serialportsync_h__7fc698bb_bf4d_449e_8de9_62b8876187cf__included_

#if _msc_ver > 1000

#pragma once

#endif // _msc_ver > 1000

class cserialportsync  

;#endif // !defined(afx_serialportsync_h__7fc698bb_bf4d_449e_8de9_62b8876187cf__included_)

2). cpp檔案:

// serialportsync.cpp: implementation of the cserialportsync class.

////

#include "stdafx.h"

//#include "serialportdemo.h"

#include "serialportsync.h"

#ifdef _debug

#undef this_file

static char this_file=__file__;

#define new debug_new

#endif

//// construction/destruction

//#define maxsendlength 20 

#define maxreceivelength 20

cserialportsync::cserialportsync()

char strport[10]=;

sprintf(strport,"com%d",nport);

m_hcom=createfile(strport, generic_read|generic_write, 0, null ,open_existing, 0,null);

if ((m_hcom==invalid_handle_value) || (m_hcom==null ))

commtimeouts ct;

ct.readintervaltimeout         = maxdword;                                  //設定超時設定

ct.readtotaltimeoutmultiplier  = 0;

ct.readtotaltimeoutconstant    = ntimeout;

ct.writetotaltimeoutmultiplier = 0;

ct.writetotaltimeoutconstant   = ntimeout; 

setcommtimeouts( m_hcom, &ct );

dcb dcb;

getcommstate( m_hcom, &dcb );

dcb.baudrate           = nbaud;

dcb.stopbits           = nstopbit;

dcb.parity             = nparity;

dcb.bytesize           = (byte)ndatabit;       // number of bits/byte, 4-8

bool bl = setcommstate( m_hcom, &dcb );

m_bopened = true;

return true;

}// nsendtype 1: 以十六進製制傳送.  0: 直接傳送字串

//返回值是已接收的個數

//返回 -1: 寫串列埠失敗. -2:清除串列埠錯誤;  -3: 串列埠返回資料為0;

dword cserialportsync::senddata(const char *sendbuffer, const unsigned int writebytes, char *recbuffer, int nsendtype)

;memset(bhexdata, 0, maxsendlength);

int len = string2hex(sendbuffer, writebytes, bhexdata);

bool bwriteret = false;

bwriteret = writefile(m_hcom, bhexdata, len, &dwwritten, null);

bool breadstatus;

byte breadbuf[maxreceivelength] = ;

breadstatus = readfile( m_hcom, breadbuf, maxreceivelength, &dwbytesread, null);

if (dwbytesread <1 ) return dwbytesread;

cstring strbuf;

cstring strtemp;

for(int i=0; ireturn dwbytesread;

}return dwbytesread;

}void cserialportsync::close()

if( m_bopened ) m_bopened = false;

}//由於這個轉換函式的格式限制,在傳送框中的十六制字元應該每兩個字元之間插入乙個空隔

//如:a1 23 45 0b 00 29

int cserialportsync::string2hex(const char *str, const unsigned int nlen, byte *senddata)

// senddata.setsize(hexdatalen);

return hexdatalen;

}//這是乙個將字元轉換為相應的十六進製制值的函式

//功能:若是在0-f之間的字元,則轉換為相應的十六進製制字元,否則返回-1

char cserialportsync::converthexchar(char ch) 

3) dll匯出函式實現:

/*返回值:

-9: 開啟串列埠失敗。

-1: 往串列埠寫資料失敗。

-2: 清除串列埠錯誤失敗。

-3: 串列埠返回資料為0。

正值: 返回正常。

*/serialport_dll int __stdcall senddata(int nport, int nbaud,int ndatabit,int nstopbit,

int nparity, const char *sendbuffer, int writebytes,

char *recbuffer, int nsendtype, int ntimeout)

int nreadcount = sport.senddata(sendbuffer, writebytes, recbuffer);

sport.close();

return nreadcount;

}4). 我為什麼要用類來實現c++的串列埠讀寫呢,主要也是方便c++開發人員可以直接使用該類,而c#的開發人員,直可以通過上面第三步,匯出

到dll中,在c#中直接呼叫。

二. c#呼叫的**就更簡單啦,像平常調api函式一樣,用dllimport宣告一下即可。這時就不多講了。

本人一直從事mobile/wince/linux平台下開發,使用c++雖有多年,但覺得自已對很多底層細節技術理解仍不夠深刻,希望有機會得到高手指點

,另對串列埠有興趣的朋友也可以一起交流,我的email:boyxd#tom.com。(#號換成@)

C 呼叫C 函式來與串列埠通訊

前些日子幫朋友寫個小軟體,要求用c 來實現主程式,主要的功能是與一些通訊裝置打交道,當然就是通過串列埠了,以十進位制傳送和讀取串列埠 的資料,考慮到c 呼叫api並沒有c 來得方便,因此,我用c 封裝了乙個讀寫串列埠的dll,只提供乙個函式供外部呼叫,這樣的好處在於,c 只要呼叫這個函式傳送完資料後...

用C呼叫C 函式來看extern C 的作用

extern c 這個東西不知道在書上和別人的 裡看到過多少次了,但是就是從來沒有好好了解過,結果有一次專案對接問題就出在了這裡。果然遇到問題才是學習的最好途徑啊!情況是這樣的 我用c 寫了大一堆東西,然後我要把自己寫的東西生成乙個動態庫給別人呼叫。但是別人在呼叫的時候,就面臨乙個問題 別人無論是用...

C 串列埠通訊

串列埠通訊類 serialportdao.csusing system using system.collections.generic using system.text using system.io.ports namespace ly.fuelstationpos.protocol set ...