前些日子幫朋友寫個小軟體,要求用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++雖有多年,但覺得自已對很多底層細節技術理解仍不夠深刻,希望有機會得到高手指點
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 ...