This commit is contained in:
“leonzor” 2025-03-06 13:47:33 +08:00
commit c16ad2537c
1854 changed files with 719455 additions and 0 deletions

8
.idea/.gitignore vendored Normal file
View File

@ -0,0 +1,8 @@
# 默认忽略的文件
/shelf/
/workspace.xml
# 基于编辑器的 HTTP 客户端请求
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

2
.idea/IPBS_NSSM.iml Normal file
View File

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<module classpath="CMake" type="CPP_MODULE" version="4" />

4
.idea/misc.xml Normal file
View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CMakeWorkspace" PROJECT_DIR="$PROJECT_DIR$" />
</project>

8
.idea/modules.xml Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/IPBS_NSSM.iml" filepath="$PROJECT_DIR$/.idea/IPBS_NSSM.iml" />
</modules>
</component>
</project>

6
.idea/vcs.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

40
CMakeLists.txt Normal file
View File

@ -0,0 +1,40 @@
cmake_minimum_required(VERSION 3.5)
project(IPBS_NSSM LANGUAGES CXX)
add_subdirectory(SDK)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# QtCreator supports the following variables for Android, which are identical to qmake Android variables.
# Check http://doc.qt.io/qt-5/deployment-android.html for more information.
# They need to be set before the find_package(Qt5 ...) call.
#if(ANDROID)
# set(ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android")
# if (ANDROID_ABI STREQUAL "armeabi-v7a")
# set(ANDROID_EXTRA_LIBS
# ${CMAKE_CURRENT_SOURCE_DIR}/path/to/libcrypto.so
# ${CMAKE_CURRENT_SOURCE_DIR}/path/to/libssl.so)
# endif()
#endif()
find_package(Qt5 COMPONENTS Widgets REQUIRED)
if(ANDROID)
add_library(IPBS_NSSM SHARED
main.cpp
)
else()
add_executable(IPBS_NSSM
# WIN32
main.cpp
)
endif()
target_include_directories(IPBS_NSSM PUBLIC SDK)
target_link_libraries(IPBS_NSSM PRIVATE Qt5::Widgets CC_API)

29680
SDK/CCServlet/SQL/shell.cpp Normal file

File diff suppressed because it is too large Load Diff

255932
SDK/CCServlet/SQL/sqlite3.cpp Normal file

File diff suppressed because it is too large Load Diff

13374
SDK/CCServlet/SQL/sqlite3.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,719 @@
/*
** 2006 June 7
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
*************************************************************************
** This header file defines the SQLite interface for use by
** shared libraries that want to be imported as extensions into
** an SQLite instance. Shared libraries that intend to be loaded
** as extensions by SQLite should #include this file instead of
** sqlite3.h.
*/
#ifndef SQLITE3EXT_H
#define SQLITE3EXT_H
#include "sqlite3.h"
/*
** The following structure holds pointers to all of the SQLite API
** routines.
**
** WARNING: In order to maintain backwards compatibility, add new
** interfaces to the end of this structure only. If you insert new
** interfaces in the middle of this structure, then older different
** versions of SQLite will not be able to load each other's shared
** libraries!
*/
struct sqlite3_api_routines {
void * (*aggregate_context)(sqlite3_context*,int nBytes);
int (*aggregate_count)(sqlite3_context*);
int (*bind_blob)(sqlite3_stmt*,int,const void*,int n,void(*)(void*));
int (*bind_double)(sqlite3_stmt*,int,double);
int (*bind_int)(sqlite3_stmt*,int,int);
int (*bind_int64)(sqlite3_stmt*,int,sqlite_int64);
int (*bind_null)(sqlite3_stmt*,int);
int (*bind_parameter_count)(sqlite3_stmt*);
int (*bind_parameter_index)(sqlite3_stmt*,const char*zName);
const char * (*bind_parameter_name)(sqlite3_stmt*,int);
int (*bind_text)(sqlite3_stmt*,int,const char*,int n,void(*)(void*));
int (*bind_text16)(sqlite3_stmt*,int,const void*,int,void(*)(void*));
int (*bind_value)(sqlite3_stmt*,int,const sqlite3_value*);
int (*busy_handler)(sqlite3*,int(*)(void*,int),void*);
int (*busy_timeout)(sqlite3*,int ms);
int (*changes)(sqlite3*);
int (*close)(sqlite3*);
int (*collation_needed)(sqlite3*,void*,void(*)(void*,sqlite3*,
int eTextRep,const char*));
int (*collation_needed16)(sqlite3*,void*,void(*)(void*,sqlite3*,
int eTextRep,const void*));
const void * (*column_blob)(sqlite3_stmt*,int iCol);
int (*column_bytes)(sqlite3_stmt*,int iCol);
int (*column_bytes16)(sqlite3_stmt*,int iCol);
int (*column_count)(sqlite3_stmt*pStmt);
const char * (*column_database_name)(sqlite3_stmt*,int);
const void * (*column_database_name16)(sqlite3_stmt*,int);
const char * (*column_decltype)(sqlite3_stmt*,int i);
const void * (*column_decltype16)(sqlite3_stmt*,int);
double (*column_double)(sqlite3_stmt*,int iCol);
int (*column_int)(sqlite3_stmt*,int iCol);
sqlite_int64 (*column_int64)(sqlite3_stmt*,int iCol);
const char * (*column_name)(sqlite3_stmt*,int);
const void * (*column_name16)(sqlite3_stmt*,int);
const char * (*column_origin_name)(sqlite3_stmt*,int);
const void * (*column_origin_name16)(sqlite3_stmt*,int);
const char * (*column_table_name)(sqlite3_stmt*,int);
const void * (*column_table_name16)(sqlite3_stmt*,int);
const unsigned char * (*column_text)(sqlite3_stmt*,int iCol);
const void * (*column_text16)(sqlite3_stmt*,int iCol);
int (*column_type)(sqlite3_stmt*,int iCol);
sqlite3_value* (*column_value)(sqlite3_stmt*,int iCol);
void * (*commit_hook)(sqlite3*,int(*)(void*),void*);
int (*complete)(const char*sql);
int (*complete16)(const void*sql);
int (*create_collation)(sqlite3*,const char*,int,void*,
int(*)(void*,int,const void*,int,const void*));
int (*create_collation16)(sqlite3*,const void*,int,void*,
int(*)(void*,int,const void*,int,const void*));
int (*create_function)(sqlite3*,const char*,int,int,void*,
void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
void (*xFinal)(sqlite3_context*));
int (*create_function16)(sqlite3*,const void*,int,int,void*,
void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
void (*xFinal)(sqlite3_context*));
int (*create_module)(sqlite3*,const char*,const sqlite3_module*,void*);
int (*data_count)(sqlite3_stmt*pStmt);
sqlite3 * (*db_handle)(sqlite3_stmt*);
int (*declare_vtab)(sqlite3*,const char*);
int (*enable_shared_cache)(int);
int (*errcode)(sqlite3*db);
const char * (*errmsg)(sqlite3*);
const void * (*errmsg16)(sqlite3*);
int (*exec)(sqlite3*,const char*,sqlite3_callback,void*,char**);
int (*expired)(sqlite3_stmt*);
int (*finalize)(sqlite3_stmt*pStmt);
void (*free)(void*);
void (*free_table)(char**result);
int (*get_autocommit)(sqlite3*);
void * (*get_auxdata)(sqlite3_context*,int);
int (*get_table)(sqlite3*,const char*,char***,int*,int*,char**);
int (*global_recover)(void);
void (*interruptx)(sqlite3*);
sqlite_int64 (*last_insert_rowid)(sqlite3*);
const char * (*libversion)(void);
int (*libversion_number)(void);
void *(*malloc)(int);
char * (*mprintf)(const char*,...);
int (*open)(const char*,sqlite3**);
int (*open16)(const void*,sqlite3**);
int (*prepare)(sqlite3*,const char*,int,sqlite3_stmt**,const char**);
int (*prepare16)(sqlite3*,const void*,int,sqlite3_stmt**,const void**);
void * (*profile)(sqlite3*,void(*)(void*,const char*,sqlite_uint64),void*);
void (*progress_handler)(sqlite3*,int,int(*)(void*),void*);
void *(*realloc)(void*,int);
int (*reset)(sqlite3_stmt*pStmt);
void (*result_blob)(sqlite3_context*,const void*,int,void(*)(void*));
void (*result_double)(sqlite3_context*,double);
void (*result_error)(sqlite3_context*,const char*,int);
void (*result_error16)(sqlite3_context*,const void*,int);
void (*result_int)(sqlite3_context*,int);
void (*result_int64)(sqlite3_context*,sqlite_int64);
void (*result_null)(sqlite3_context*);
void (*result_text)(sqlite3_context*,const char*,int,void(*)(void*));
void (*result_text16)(sqlite3_context*,const void*,int,void(*)(void*));
void (*result_text16be)(sqlite3_context*,const void*,int,void(*)(void*));
void (*result_text16le)(sqlite3_context*,const void*,int,void(*)(void*));
void (*result_value)(sqlite3_context*,sqlite3_value*);
void * (*rollback_hook)(sqlite3*,void(*)(void*),void*);
int (*set_authorizer)(sqlite3*,int(*)(void*,int,const char*,const char*,
const char*,const char*),void*);
void (*set_auxdata)(sqlite3_context*,int,void*,void (*)(void*));
char * (*xsnprintf)(int,char*,const char*,...);
int (*step)(sqlite3_stmt*);
int (*table_column_metadata)(sqlite3*,const char*,const char*,const char*,
char const**,char const**,int*,int*,int*);
void (*thread_cleanup)(void);
int (*total_changes)(sqlite3*);
void * (*trace)(sqlite3*,void(*xTrace)(void*,const char*),void*);
int (*transfer_bindings)(sqlite3_stmt*,sqlite3_stmt*);
void * (*update_hook)(sqlite3*,void(*)(void*,int ,char const*,char const*,
sqlite_int64),void*);
void * (*user_data)(sqlite3_context*);
const void * (*value_blob)(sqlite3_value*);
int (*value_bytes)(sqlite3_value*);
int (*value_bytes16)(sqlite3_value*);
double (*value_double)(sqlite3_value*);
int (*value_int)(sqlite3_value*);
sqlite_int64 (*value_int64)(sqlite3_value*);
int (*value_numeric_type)(sqlite3_value*);
const unsigned char * (*value_text)(sqlite3_value*);
const void * (*value_text16)(sqlite3_value*);
const void * (*value_text16be)(sqlite3_value*);
const void * (*value_text16le)(sqlite3_value*);
int (*value_type)(sqlite3_value*);
char *(*vmprintf)(const char*,va_list);
/* Added ??? */
int (*overload_function)(sqlite3*, const char *zFuncName, int nArg);
/* Added by 3.3.13 */
int (*prepare_v2)(sqlite3*,const char*,int,sqlite3_stmt**,const char**);
int (*prepare16_v2)(sqlite3*,const void*,int,sqlite3_stmt**,const void**);
int (*clear_bindings)(sqlite3_stmt*);
/* Added by 3.4.1 */
int (*create_module_v2)(sqlite3*,const char*,const sqlite3_module*,void*,
void (*xDestroy)(void *));
/* Added by 3.5.0 */
int (*bind_zeroblob)(sqlite3_stmt*,int,int);
int (*blob_bytes)(sqlite3_blob*);
int (*blob_close)(sqlite3_blob*);
int (*blob_open)(sqlite3*,const char*,const char*,const char*,sqlite3_int64,
int,sqlite3_blob**);
int (*blob_read)(sqlite3_blob*,void*,int,int);
int (*blob_write)(sqlite3_blob*,const void*,int,int);
int (*create_collation_v2)(sqlite3*,const char*,int,void*,
int(*)(void*,int,const void*,int,const void*),
void(*)(void*));
int (*file_control)(sqlite3*,const char*,int,void*);
sqlite3_int64 (*memory_highwater)(int);
sqlite3_int64 (*memory_used)(void);
sqlite3_mutex *(*mutex_alloc)(int);
void (*mutex_enter)(sqlite3_mutex*);
void (*mutex_free)(sqlite3_mutex*);
void (*mutex_leave)(sqlite3_mutex*);
int (*mutex_try)(sqlite3_mutex*);
int (*open_v2)(const char*,sqlite3**,int,const char*);
int (*release_memory)(int);
void (*result_error_nomem)(sqlite3_context*);
void (*result_error_toobig)(sqlite3_context*);
int (*sleep)(int);
void (*soft_heap_limit)(int);
sqlite3_vfs *(*vfs_find)(const char*);
int (*vfs_register)(sqlite3_vfs*,int);
int (*vfs_unregister)(sqlite3_vfs*);
int (*xthreadsafe)(void);
void (*result_zeroblob)(sqlite3_context*,int);
void (*result_error_code)(sqlite3_context*,int);
int (*test_control)(int, ...);
void (*randomness)(int,void*);
sqlite3 *(*context_db_handle)(sqlite3_context*);
int (*extended_result_codes)(sqlite3*,int);
int (*limit)(sqlite3*,int,int);
sqlite3_stmt *(*next_stmt)(sqlite3*,sqlite3_stmt*);
const char *(*sql)(sqlite3_stmt*);
int (*status)(int,int*,int*,int);
int (*backup_finish)(sqlite3_backup*);
sqlite3_backup *(*backup_init)(sqlite3*,const char*,sqlite3*,const char*);
int (*backup_pagecount)(sqlite3_backup*);
int (*backup_remaining)(sqlite3_backup*);
int (*backup_step)(sqlite3_backup*,int);
const char *(*compileoption_get)(int);
int (*compileoption_used)(const char*);
int (*create_function_v2)(sqlite3*,const char*,int,int,void*,
void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
void (*xFinal)(sqlite3_context*),
void(*xDestroy)(void*));
int (*db_config)(sqlite3*,int,...);
sqlite3_mutex *(*db_mutex)(sqlite3*);
int (*db_status)(sqlite3*,int,int*,int*,int);
int (*extended_errcode)(sqlite3*);
void (*log)(int,const char*,...);
sqlite3_int64 (*soft_heap_limit64)(sqlite3_int64);
const char *(*sourceid)(void);
int (*stmt_status)(sqlite3_stmt*,int,int);
int (*strnicmp)(const char*,const char*,int);
int (*unlock_notify)(sqlite3*,void(*)(void**,int),void*);
int (*wal_autocheckpoint)(sqlite3*,int);
int (*wal_checkpoint)(sqlite3*,const char*);
void *(*wal_hook)(sqlite3*,int(*)(void*,sqlite3*,const char*,int),void*);
int (*blob_reopen)(sqlite3_blob*,sqlite3_int64);
int (*vtab_config)(sqlite3*,int op,...);
int (*vtab_on_conflict)(sqlite3*);
/* Version 3.7.16 and later */
int (*close_v2)(sqlite3*);
const char *(*db_filename)(sqlite3*,const char*);
int (*db_readonly)(sqlite3*,const char*);
int (*db_release_memory)(sqlite3*);
const char *(*errstr)(int);
int (*stmt_busy)(sqlite3_stmt*);
int (*stmt_readonly)(sqlite3_stmt*);
int (*stricmp)(const char*,const char*);
int (*uri_boolean)(const char*,const char*,int);
sqlite3_int64 (*uri_int64)(const char*,const char*,sqlite3_int64);
const char *(*uri_parameter)(const char*,const char*);
char *(*xvsnprintf)(int,char*,const char*,va_list);
int (*wal_checkpoint_v2)(sqlite3*,const char*,int,int*,int*);
/* Version 3.8.7 and later */
int (*auto_extension)(void(*)(void));
int (*bind_blob64)(sqlite3_stmt*,int,const void*,sqlite3_uint64,
void(*)(void*));
int (*bind_text64)(sqlite3_stmt*,int,const char*,sqlite3_uint64,
void(*)(void*),unsigned char);
int (*cancel_auto_extension)(void(*)(void));
int (*load_extension)(sqlite3*,const char*,const char*,char**);
void *(*malloc64)(sqlite3_uint64);
sqlite3_uint64 (*msize)(void*);
void *(*realloc64)(void*,sqlite3_uint64);
void (*reset_auto_extension)(void);
void (*result_blob64)(sqlite3_context*,const void*,sqlite3_uint64,
void(*)(void*));
void (*result_text64)(sqlite3_context*,const char*,sqlite3_uint64,
void(*)(void*), unsigned char);
int (*strglob)(const char*,const char*);
/* Version 3.8.11 and later */
sqlite3_value *(*value_dup)(const sqlite3_value*);
void (*value_free)(sqlite3_value*);
int (*result_zeroblob64)(sqlite3_context*,sqlite3_uint64);
int (*bind_zeroblob64)(sqlite3_stmt*, int, sqlite3_uint64);
/* Version 3.9.0 and later */
unsigned int (*value_subtype)(sqlite3_value*);
void (*result_subtype)(sqlite3_context*,unsigned int);
/* Version 3.10.0 and later */
int (*status64)(int,sqlite3_int64*,sqlite3_int64*,int);
int (*strlike)(const char*,const char*,unsigned int);
int (*db_cacheflush)(sqlite3*);
/* Version 3.12.0 and later */
int (*system_errno)(sqlite3*);
/* Version 3.14.0 and later */
int (*trace_v2)(sqlite3*,unsigned,int(*)(unsigned,void*,void*,void*),void*);
char *(*expanded_sql)(sqlite3_stmt*);
/* Version 3.18.0 and later */
void (*set_last_insert_rowid)(sqlite3*,sqlite3_int64);
/* Version 3.20.0 and later */
int (*prepare_v3)(sqlite3*,const char*,int,unsigned int,
sqlite3_stmt**,const char**);
int (*prepare16_v3)(sqlite3*,const void*,int,unsigned int,
sqlite3_stmt**,const void**);
int (*bind_pointer)(sqlite3_stmt*,int,void*,const char*,void(*)(void*));
void (*result_pointer)(sqlite3_context*,void*,const char*,void(*)(void*));
void *(*value_pointer)(sqlite3_value*,const char*);
int (*vtab_nochange)(sqlite3_context*);
int (*value_nochange)(sqlite3_value*);
const char *(*vtab_collation)(sqlite3_index_info*,int);
/* Version 3.24.0 and later */
int (*keyword_count)(void);
int (*keyword_name)(int,const char**,int*);
int (*keyword_check)(const char*,int);
sqlite3_str *(*str_new)(sqlite3*);
char *(*str_finish)(sqlite3_str*);
void (*str_appendf)(sqlite3_str*, const char *zFormat, ...);
void (*str_vappendf)(sqlite3_str*, const char *zFormat, va_list);
void (*str_append)(sqlite3_str*, const char *zIn, int N);
void (*str_appendall)(sqlite3_str*, const char *zIn);
void (*str_appendchar)(sqlite3_str*, int N, char C);
void (*str_reset)(sqlite3_str*);
int (*str_errcode)(sqlite3_str*);
int (*str_length)(sqlite3_str*);
char *(*str_value)(sqlite3_str*);
/* Version 3.25.0 and later */
int (*create_window_function)(sqlite3*,const char*,int,int,void*,
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
void (*xFinal)(sqlite3_context*),
void (*xValue)(sqlite3_context*),
void (*xInv)(sqlite3_context*,int,sqlite3_value**),
void(*xDestroy)(void*));
/* Version 3.26.0 and later */
const char *(*normalized_sql)(sqlite3_stmt*);
/* Version 3.28.0 and later */
int (*stmt_isexplain)(sqlite3_stmt*);
int (*value_frombind)(sqlite3_value*);
/* Version 3.30.0 and later */
int (*drop_modules)(sqlite3*,const char**);
/* Version 3.31.0 and later */
sqlite3_int64 (*hard_heap_limit64)(sqlite3_int64);
const char *(*uri_key)(const char*,int);
const char *(*filename_database)(const char*);
const char *(*filename_journal)(const char*);
const char *(*filename_wal)(const char*);
/* Version 3.32.0 and later */
const char *(*create_filename)(const char*,const char*,const char*,
int,const char**);
void (*free_filename)(const char*);
sqlite3_file *(*database_file_object)(const char*);
/* Version 3.34.0 and later */
int (*txn_state)(sqlite3*,const char*);
/* Version 3.36.1 and later */
sqlite3_int64 (*changes64)(sqlite3*);
sqlite3_int64 (*total_changes64)(sqlite3*);
/* Version 3.37.0 and later */
int (*autovacuum_pages)(sqlite3*,
unsigned int(*)(void*,const char*,unsigned int,unsigned int,unsigned int),
void*, void(*)(void*));
/* Version 3.38.0 and later */
int (*error_offset)(sqlite3*);
int (*vtab_rhs_value)(sqlite3_index_info*,int,sqlite3_value**);
int (*vtab_distinct)(sqlite3_index_info*);
int (*vtab_in)(sqlite3_index_info*,int,int);
int (*vtab_in_first)(sqlite3_value*,sqlite3_value**);
int (*vtab_in_next)(sqlite3_value*,sqlite3_value**);
/* Version 3.39.0 and later */
int (*deserialize)(sqlite3*,const char*,unsigned char*,
sqlite3_int64,sqlite3_int64,unsigned);
unsigned char *(*serialize)(sqlite3*,const char *,sqlite3_int64*,
unsigned int);
const char *(*db_name)(sqlite3*,int);
/* Version 3.40.0 and later */
int (*value_encoding)(sqlite3_value*);
/* Version 3.41.0 and later */
int (*is_interrupted)(sqlite3*);
/* Version 3.43.0 and later */
int (*stmt_explain)(sqlite3_stmt*,int);
/* Version 3.44.0 and later */
void *(*get_clientdata)(sqlite3*,const char*);
int (*set_clientdata)(sqlite3*, const char*, void*, void(*)(void*));
};
/*
** This is the function signature used for all extension entry points. It
** is also defined in the file "loadext.c".
*/
typedef int (*sqlite3_loadext_entry)(
sqlite3 *db, /* Handle to the database. */
char **pzErrMsg, /* Used to set error string on failure. */
const sqlite3_api_routines *pThunk /* Extension API function pointers. */
);
/*
** The following macros redefine the API routines so that they are
** redirected through the global sqlite3_api structure.
**
** This header file is also used by the loadext.c source file
** (part of the main SQLite library - not an extension) so that
** it can get access to the sqlite3_api_routines structure
** definition. But the main library does not want to redefine
** the API. So the redefinition macros are only valid if the
** SQLITE_CORE macros is undefined.
*/
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
#define sqlite3_aggregate_context sqlite3_api->aggregate_context
#ifndef SQLITE_OMIT_DEPRECATED
#define sqlite3_aggregate_count sqlite3_api->aggregate_count
#endif
#define sqlite3_bind_blob sqlite3_api->bind_blob
#define sqlite3_bind_double sqlite3_api->bind_double
#define sqlite3_bind_int sqlite3_api->bind_int
#define sqlite3_bind_int64 sqlite3_api->bind_int64
#define sqlite3_bind_null sqlite3_api->bind_null
#define sqlite3_bind_parameter_count sqlite3_api->bind_parameter_count
#define sqlite3_bind_parameter_index sqlite3_api->bind_parameter_index
#define sqlite3_bind_parameter_name sqlite3_api->bind_parameter_name
#define sqlite3_bind_text sqlite3_api->bind_text
#define sqlite3_bind_text16 sqlite3_api->bind_text16
#define sqlite3_bind_value sqlite3_api->bind_value
#define sqlite3_busy_handler sqlite3_api->busy_handler
#define sqlite3_busy_timeout sqlite3_api->busy_timeout
#define sqlite3_changes sqlite3_api->changes
#define sqlite3_close sqlite3_api->close
#define sqlite3_collation_needed sqlite3_api->collation_needed
#define sqlite3_collation_needed16 sqlite3_api->collation_needed16
#define sqlite3_column_blob sqlite3_api->column_blob
#define sqlite3_column_bytes sqlite3_api->column_bytes
#define sqlite3_column_bytes16 sqlite3_api->column_bytes16
#define sqlite3_column_count sqlite3_api->column_count
#define sqlite3_column_database_name sqlite3_api->column_database_name
#define sqlite3_column_database_name16 sqlite3_api->column_database_name16
#define sqlite3_column_decltype sqlite3_api->column_decltype
#define sqlite3_column_decltype16 sqlite3_api->column_decltype16
#define sqlite3_column_double sqlite3_api->column_double
#define sqlite3_column_int sqlite3_api->column_int
#define sqlite3_column_int64 sqlite3_api->column_int64
#define sqlite3_column_name sqlite3_api->column_name
#define sqlite3_column_name16 sqlite3_api->column_name16
#define sqlite3_column_origin_name sqlite3_api->column_origin_name
#define sqlite3_column_origin_name16 sqlite3_api->column_origin_name16
#define sqlite3_column_table_name sqlite3_api->column_table_name
#define sqlite3_column_table_name16 sqlite3_api->column_table_name16
#define sqlite3_column_text sqlite3_api->column_text
#define sqlite3_column_text16 sqlite3_api->column_text16
#define sqlite3_column_type sqlite3_api->column_type
#define sqlite3_column_value sqlite3_api->column_value
#define sqlite3_commit_hook sqlite3_api->commit_hook
#define sqlite3_complete sqlite3_api->complete
#define sqlite3_complete16 sqlite3_api->complete16
#define sqlite3_create_collation sqlite3_api->create_collation
#define sqlite3_create_collation16 sqlite3_api->create_collation16
#define sqlite3_create_function sqlite3_api->create_function
#define sqlite3_create_function16 sqlite3_api->create_function16
#define sqlite3_create_module sqlite3_api->create_module
#define sqlite3_create_module_v2 sqlite3_api->create_module_v2
#define sqlite3_data_count sqlite3_api->data_count
#define sqlite3_db_handle sqlite3_api->db_handle
#define sqlite3_declare_vtab sqlite3_api->declare_vtab
#define sqlite3_enable_shared_cache sqlite3_api->enable_shared_cache
#define sqlite3_errcode sqlite3_api->errcode
#define sqlite3_errmsg sqlite3_api->errmsg
#define sqlite3_errmsg16 sqlite3_api->errmsg16
#define sqlite3_exec sqlite3_api->exec
#ifndef SQLITE_OMIT_DEPRECATED
#define sqlite3_expired sqlite3_api->expired
#endif
#define sqlite3_finalize sqlite3_api->finalize
#define sqlite3_free sqlite3_api->free
#define sqlite3_free_table sqlite3_api->free_table
#define sqlite3_get_autocommit sqlite3_api->get_autocommit
#define sqlite3_get_auxdata sqlite3_api->get_auxdata
#define sqlite3_get_table sqlite3_api->get_table
#ifndef SQLITE_OMIT_DEPRECATED
#define sqlite3_global_recover sqlite3_api->global_recover
#endif
#define sqlite3_interrupt sqlite3_api->interruptx
#define sqlite3_last_insert_rowid sqlite3_api->last_insert_rowid
#define sqlite3_libversion sqlite3_api->libversion
#define sqlite3_libversion_number sqlite3_api->libversion_number
#define sqlite3_malloc sqlite3_api->malloc
#define sqlite3_mprintf sqlite3_api->mprintf
#define sqlite3_open sqlite3_api->open
#define sqlite3_open16 sqlite3_api->open16
#define sqlite3_prepare sqlite3_api->prepare
#define sqlite3_prepare16 sqlite3_api->prepare16
#define sqlite3_prepare_v2 sqlite3_api->prepare_v2
#define sqlite3_prepare16_v2 sqlite3_api->prepare16_v2
#define sqlite3_profile sqlite3_api->profile
#define sqlite3_progress_handler sqlite3_api->progress_handler
#define sqlite3_realloc sqlite3_api->realloc
#define sqlite3_reset sqlite3_api->reset
#define sqlite3_result_blob sqlite3_api->result_blob
#define sqlite3_result_double sqlite3_api->result_double
#define sqlite3_result_error sqlite3_api->result_error
#define sqlite3_result_error16 sqlite3_api->result_error16
#define sqlite3_result_int sqlite3_api->result_int
#define sqlite3_result_int64 sqlite3_api->result_int64
#define sqlite3_result_null sqlite3_api->result_null
#define sqlite3_result_text sqlite3_api->result_text
#define sqlite3_result_text16 sqlite3_api->result_text16
#define sqlite3_result_text16be sqlite3_api->result_text16be
#define sqlite3_result_text16le sqlite3_api->result_text16le
#define sqlite3_result_value sqlite3_api->result_value
#define sqlite3_rollback_hook sqlite3_api->rollback_hook
#define sqlite3_set_authorizer sqlite3_api->set_authorizer
#define sqlite3_set_auxdata sqlite3_api->set_auxdata
#define sqlite3_snprintf sqlite3_api->xsnprintf
#define sqlite3_step sqlite3_api->step
#define sqlite3_table_column_metadata sqlite3_api->table_column_metadata
#define sqlite3_thread_cleanup sqlite3_api->thread_cleanup
#define sqlite3_total_changes sqlite3_api->total_changes
#define sqlite3_trace sqlite3_api->trace
#ifndef SQLITE_OMIT_DEPRECATED
#define sqlite3_transfer_bindings sqlite3_api->transfer_bindings
#endif
#define sqlite3_update_hook sqlite3_api->update_hook
#define sqlite3_user_data sqlite3_api->user_data
#define sqlite3_value_blob sqlite3_api->value_blob
#define sqlite3_value_bytes sqlite3_api->value_bytes
#define sqlite3_value_bytes16 sqlite3_api->value_bytes16
#define sqlite3_value_double sqlite3_api->value_double
#define sqlite3_value_int sqlite3_api->value_int
#define sqlite3_value_int64 sqlite3_api->value_int64
#define sqlite3_value_numeric_type sqlite3_api->value_numeric_type
#define sqlite3_value_text sqlite3_api->value_text
#define sqlite3_value_text16 sqlite3_api->value_text16
#define sqlite3_value_text16be sqlite3_api->value_text16be
#define sqlite3_value_text16le sqlite3_api->value_text16le
#define sqlite3_value_type sqlite3_api->value_type
#define sqlite3_vmprintf sqlite3_api->vmprintf
#define sqlite3_vsnprintf sqlite3_api->xvsnprintf
#define sqlite3_overload_function sqlite3_api->overload_function
#define sqlite3_prepare_v2 sqlite3_api->prepare_v2
#define sqlite3_prepare16_v2 sqlite3_api->prepare16_v2
#define sqlite3_clear_bindings sqlite3_api->clear_bindings
#define sqlite3_bind_zeroblob sqlite3_api->bind_zeroblob
#define sqlite3_blob_bytes sqlite3_api->blob_bytes
#define sqlite3_blob_close sqlite3_api->blob_close
#define sqlite3_blob_open sqlite3_api->blob_open
#define sqlite3_blob_read sqlite3_api->blob_read
#define sqlite3_blob_write sqlite3_api->blob_write
#define sqlite3_create_collation_v2 sqlite3_api->create_collation_v2
#define sqlite3_file_control sqlite3_api->file_control
#define sqlite3_memory_highwater sqlite3_api->memory_highwater
#define sqlite3_memory_used sqlite3_api->memory_used
#define sqlite3_mutex_alloc sqlite3_api->mutex_alloc
#define sqlite3_mutex_enter sqlite3_api->mutex_enter
#define sqlite3_mutex_free sqlite3_api->mutex_free
#define sqlite3_mutex_leave sqlite3_api->mutex_leave
#define sqlite3_mutex_try sqlite3_api->mutex_try
#define sqlite3_open_v2 sqlite3_api->open_v2
#define sqlite3_release_memory sqlite3_api->release_memory
#define sqlite3_result_error_nomem sqlite3_api->result_error_nomem
#define sqlite3_result_error_toobig sqlite3_api->result_error_toobig
#define sqlite3_sleep sqlite3_api->sleep
#define sqlite3_soft_heap_limit sqlite3_api->soft_heap_limit
#define sqlite3_vfs_find sqlite3_api->vfs_find
#define sqlite3_vfs_register sqlite3_api->vfs_register
#define sqlite3_vfs_unregister sqlite3_api->vfs_unregister
#define sqlite3_threadsafe sqlite3_api->xthreadsafe
#define sqlite3_result_zeroblob sqlite3_api->result_zeroblob
#define sqlite3_result_error_code sqlite3_api->result_error_code
#define sqlite3_test_control sqlite3_api->test_control
#define sqlite3_randomness sqlite3_api->randomness
#define sqlite3_context_db_handle sqlite3_api->context_db_handle
#define sqlite3_extended_result_codes sqlite3_api->extended_result_codes
#define sqlite3_limit sqlite3_api->limit
#define sqlite3_next_stmt sqlite3_api->next_stmt
#define sqlite3_sql sqlite3_api->sql
#define sqlite3_status sqlite3_api->status
#define sqlite3_backup_finish sqlite3_api->backup_finish
#define sqlite3_backup_init sqlite3_api->backup_init
#define sqlite3_backup_pagecount sqlite3_api->backup_pagecount
#define sqlite3_backup_remaining sqlite3_api->backup_remaining
#define sqlite3_backup_step sqlite3_api->backup_step
#define sqlite3_compileoption_get sqlite3_api->compileoption_get
#define sqlite3_compileoption_used sqlite3_api->compileoption_used
#define sqlite3_create_function_v2 sqlite3_api->create_function_v2
#define sqlite3_db_config sqlite3_api->db_config
#define sqlite3_db_mutex sqlite3_api->db_mutex
#define sqlite3_db_status sqlite3_api->db_status
#define sqlite3_extended_errcode sqlite3_api->extended_errcode
#define sqlite3_log sqlite3_api->log
#define sqlite3_soft_heap_limit64 sqlite3_api->soft_heap_limit64
#define sqlite3_sourceid sqlite3_api->sourceid
#define sqlite3_stmt_status sqlite3_api->stmt_status
#define sqlite3_strnicmp sqlite3_api->strnicmp
#define sqlite3_unlock_notify sqlite3_api->unlock_notify
#define sqlite3_wal_autocheckpoint sqlite3_api->wal_autocheckpoint
#define sqlite3_wal_checkpoint sqlite3_api->wal_checkpoint
#define sqlite3_wal_hook sqlite3_api->wal_hook
#define sqlite3_blob_reopen sqlite3_api->blob_reopen
#define sqlite3_vtab_config sqlite3_api->vtab_config
#define sqlite3_vtab_on_conflict sqlite3_api->vtab_on_conflict
/* Version 3.7.16 and later */
#define sqlite3_close_v2 sqlite3_api->close_v2
#define sqlite3_db_filename sqlite3_api->db_filename
#define sqlite3_db_readonly sqlite3_api->db_readonly
#define sqlite3_db_release_memory sqlite3_api->db_release_memory
#define sqlite3_errstr sqlite3_api->errstr
#define sqlite3_stmt_busy sqlite3_api->stmt_busy
#define sqlite3_stmt_readonly sqlite3_api->stmt_readonly
#define sqlite3_stricmp sqlite3_api->stricmp
#define sqlite3_uri_boolean sqlite3_api->uri_boolean
#define sqlite3_uri_int64 sqlite3_api->uri_int64
#define sqlite3_uri_parameter sqlite3_api->uri_parameter
#define sqlite3_uri_vsnprintf sqlite3_api->xvsnprintf
#define sqlite3_wal_checkpoint_v2 sqlite3_api->wal_checkpoint_v2
/* Version 3.8.7 and later */
#define sqlite3_auto_extension sqlite3_api->auto_extension
#define sqlite3_bind_blob64 sqlite3_api->bind_blob64
#define sqlite3_bind_text64 sqlite3_api->bind_text64
#define sqlite3_cancel_auto_extension sqlite3_api->cancel_auto_extension
#define sqlite3_load_extension sqlite3_api->load_extension
#define sqlite3_malloc64 sqlite3_api->malloc64
#define sqlite3_msize sqlite3_api->msize
#define sqlite3_realloc64 sqlite3_api->realloc64
#define sqlite3_reset_auto_extension sqlite3_api->reset_auto_extension
#define sqlite3_result_blob64 sqlite3_api->result_blob64
#define sqlite3_result_text64 sqlite3_api->result_text64
#define sqlite3_strglob sqlite3_api->strglob
/* Version 3.8.11 and later */
#define sqlite3_value_dup sqlite3_api->value_dup
#define sqlite3_value_free sqlite3_api->value_free
#define sqlite3_result_zeroblob64 sqlite3_api->result_zeroblob64
#define sqlite3_bind_zeroblob64 sqlite3_api->bind_zeroblob64
/* Version 3.9.0 and later */
#define sqlite3_value_subtype sqlite3_api->value_subtype
#define sqlite3_result_subtype sqlite3_api->result_subtype
/* Version 3.10.0 and later */
#define sqlite3_status64 sqlite3_api->status64
#define sqlite3_strlike sqlite3_api->strlike
#define sqlite3_db_cacheflush sqlite3_api->db_cacheflush
/* Version 3.12.0 and later */
#define sqlite3_system_errno sqlite3_api->system_errno
/* Version 3.14.0 and later */
#define sqlite3_trace_v2 sqlite3_api->trace_v2
#define sqlite3_expanded_sql sqlite3_api->expanded_sql
/* Version 3.18.0 and later */
#define sqlite3_set_last_insert_rowid sqlite3_api->set_last_insert_rowid
/* Version 3.20.0 and later */
#define sqlite3_prepare_v3 sqlite3_api->prepare_v3
#define sqlite3_prepare16_v3 sqlite3_api->prepare16_v3
#define sqlite3_bind_pointer sqlite3_api->bind_pointer
#define sqlite3_result_pointer sqlite3_api->result_pointer
#define sqlite3_value_pointer sqlite3_api->value_pointer
/* Version 3.22.0 and later */
#define sqlite3_vtab_nochange sqlite3_api->vtab_nochange
#define sqlite3_value_nochange sqlite3_api->value_nochange
#define sqlite3_vtab_collation sqlite3_api->vtab_collation
/* Version 3.24.0 and later */
#define sqlite3_keyword_count sqlite3_api->keyword_count
#define sqlite3_keyword_name sqlite3_api->keyword_name
#define sqlite3_keyword_check sqlite3_api->keyword_check
#define sqlite3_str_new sqlite3_api->str_new
#define sqlite3_str_finish sqlite3_api->str_finish
#define sqlite3_str_appendf sqlite3_api->str_appendf
#define sqlite3_str_vappendf sqlite3_api->str_vappendf
#define sqlite3_str_append sqlite3_api->str_append
#define sqlite3_str_appendall sqlite3_api->str_appendall
#define sqlite3_str_appendchar sqlite3_api->str_appendchar
#define sqlite3_str_reset sqlite3_api->str_reset
#define sqlite3_str_errcode sqlite3_api->str_errcode
#define sqlite3_str_length sqlite3_api->str_length
#define sqlite3_str_value sqlite3_api->str_value
/* Version 3.25.0 and later */
#define sqlite3_create_window_function sqlite3_api->create_window_function
/* Version 3.26.0 and later */
#define sqlite3_normalized_sql sqlite3_api->normalized_sql
/* Version 3.28.0 and later */
#define sqlite3_stmt_isexplain sqlite3_api->stmt_isexplain
#define sqlite3_value_frombind sqlite3_api->value_frombind
/* Version 3.30.0 and later */
#define sqlite3_drop_modules sqlite3_api->drop_modules
/* Version 3.31.0 and later */
#define sqlite3_hard_heap_limit64 sqlite3_api->hard_heap_limit64
#define sqlite3_uri_key sqlite3_api->uri_key
#define sqlite3_filename_database sqlite3_api->filename_database
#define sqlite3_filename_journal sqlite3_api->filename_journal
#define sqlite3_filename_wal sqlite3_api->filename_wal
/* Version 3.32.0 and later */
#define sqlite3_create_filename sqlite3_api->create_filename
#define sqlite3_free_filename sqlite3_api->free_filename
#define sqlite3_database_file_object sqlite3_api->database_file_object
/* Version 3.34.0 and later */
#define sqlite3_txn_state sqlite3_api->txn_state
/* Version 3.36.1 and later */
#define sqlite3_changes64 sqlite3_api->changes64
#define sqlite3_total_changes64 sqlite3_api->total_changes64
/* Version 3.37.0 and later */
#define sqlite3_autovacuum_pages sqlite3_api->autovacuum_pages
/* Version 3.38.0 and later */
#define sqlite3_error_offset sqlite3_api->error_offset
#define sqlite3_vtab_rhs_value sqlite3_api->vtab_rhs_value
#define sqlite3_vtab_distinct sqlite3_api->vtab_distinct
#define sqlite3_vtab_in sqlite3_api->vtab_in
#define sqlite3_vtab_in_first sqlite3_api->vtab_in_first
#define sqlite3_vtab_in_next sqlite3_api->vtab_in_next
/* Version 3.39.0 and later */
#ifndef SQLITE_OMIT_DESERIALIZE
#define sqlite3_deserialize sqlite3_api->deserialize
#define sqlite3_serialize sqlite3_api->serialize
#endif
#define sqlite3_db_name sqlite3_api->db_name
/* Version 3.40.0 and later */
#define sqlite3_value_encoding sqlite3_api->value_encoding
/* Version 3.41.0 and later */
#define sqlite3_is_interrupted sqlite3_api->is_interrupted
/* Version 3.43.0 and later */
#define sqlite3_stmt_explain sqlite3_api->stmt_explain
/* Version 3.44.0 and later */
#define sqlite3_get_clientdata sqlite3_api->get_clientdata
#define sqlite3_set_clientdata sqlite3_api->set_clientdata
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
/* This case when the file really is being compiled as a loadable
** extension */
# define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api=0;
# define SQLITE_EXTENSION_INIT2(v) sqlite3_api=v;
# define SQLITE_EXTENSION_INIT3 \
extern const sqlite3_api_routines *sqlite3_api;
#else
/* This case when the file is being statically linked into the
** application */
# define SQLITE_EXTENSION_INIT1 /*no-op*/
# define SQLITE_EXTENSION_INIT2(v) (void)v; /* unused parameter */
# define SQLITE_EXTENSION_INIT3 /*no-op*/
#endif
#endif /* SQLITE3EXT_H */

View File

@ -0,0 +1,94 @@
#ifndef CCWeb_Request_H
#define CCWeb_Request_H
#pragma once
#include "CCString.h"
#include "map"
#include <sys/stat.h>
#include "CORS.h"
#include "../../include/CCJSONObject.h"
#include "../../include/CCFile.h"
#include "../../include/CCSocket.h"
enum RequestProcess
{
RequestProcess_First,
RequestProcess_Header,
RequestProcess_Body,
};
struct BufferReader
{
CCString Body;
CCString Method;
CCString Path;
CCString Version;
};
struct BufferFile
{
BufferFile() = default;
std::vector<char> Buffer;
std::map<CCString,CCString> Headers;
CCString GetFileName();
bool Save(const CCString& Path);
};
enum MethodType
{
MethodType_GET,
MethodType_POST,
MethodType_PUT,
MethodType_DELETE,
MethodType_HEAD,
MethodType_OPTIONS,
};
class OutPutStream
{
private:
CCString RMethod = "GET";
CCString RPath,RBody;
std::map<CCString,CCString> SendHeaders = {{"Method",RMethod}};
CCSocket Socket;
public:
OutPutStream(CCSocket& sc);
void SetMethod(MethodType method);
void AddHeader(const CCString& Key,const CCString& Value);
void SetHost(const CCString& host);
void SetBufferBody(CCString body);
void Send();
};
class CCRequest
{
private:
BufferReader Buffer;
public:
std::map<CCString,CCString> Headers;
public:
CCRequest() = default;
CCRequest(CCSocket& sc);
CCString GetFileSuffix(const CCString& filePath);
CCString GetFileType(const CCString& str);
unsigned int GetFileSize(const char* path);
void SetBuffer(BufferReader& buffer);
BufferReader GetReader();
JSON GetJson(const BufferReader& instr);
BufferFile GetFile(BufferReader in);
CCString GetParameter(CCString string);
OutPutStream GetWiter();
private:
std::map<std::string, std::string> parseKeyValuePairs(const std::string& input);
void GetFormData(CCString& input,CCString& key,CCString& value);
CCString GetFileDateHeader(BufferReader in,std::map<CCString,CCString>& map);
std::vector<char> ReaderFormData(BufferReader in, std::map<CCString, CCString> &map);
CCSocket Socket;
};
#endif

View File

@ -0,0 +1,50 @@
#ifndef CCWeb_Response_H
#define CCWeb_Response_H
#pragma once
#include "CCRequest.h"
#include "../../include/CCSocket.h"
#include "CCString.h"
#include "mutex"
class HTTPResponse: public CCRequest, public CORS {
public:
HTTPResponse() = default;
HTTPResponse(CCSocket& socket,CORS& cors);
void HtmlTextWrite(const CCString& str);
bool HtmlWrite(const CCString& str);
void Write(const CCString& str,const char* type = "text/plain");
bool WriteFile(const CCString& Path);
void Send(const CCString& string);
void ResponseOK();
private:
bool SendResources(const char* Path, const char* Mode = "rb");
CCSocket Client;
std::mutex Mutex;
CORS CORSConfig;
private:
};
class CCResponse:public HTTPResponse
{
public:
public:
CCResponse() = default;
CCResponse(CCSocket& socket,CORS& cors);
HTTPResponse GetWiter();
private:
CCSocket Client;
CORS Cors;
};
#endif

View File

@ -0,0 +1,75 @@
#ifndef THREADPOOLDEMO_CCSQLITE3_H
#define THREADPOOLDEMO_CCSQLITE3_H
#pragma once
#include "sqlite3.h"
#include "CCString.h"
#include "vector"
#include "mutex"
#include "CCJSONObject.h"
/*
* CREATE TABLE database_name.table_name(
column1 datatype PRIMARY KEY(one or more columns),
column2 datatype,
column3 datatype,
.....
columnN datatype,);
* DROP TABLE database_name.table_name;
* INSERT INTO TABLE_NAME VALUES (value1,value2,value3,...valueN);
* SELECT * FROM table_name;
* SELECT * FROM table_name WHERE xx='xx';
* UPDATE xxx SET ADDRESS = 'Texas' WHERE xxx = xxx;
* DELETE FROM table_name WHERE xxx=xxx;
*
* */
struct CCResultSet
{
std::vector<JSON> Data;
int Row = 0;
int Col = 0;
bool Flag = false;
};
class CCSQLite3
{
public:
CCSQLite3(CCString Path);
bool Open(CCString Path);
bool Close();
bool SqlUpdate(CCString sql);
CCResultSet SqlQuery(CCString sql);
CCString GetError();
private:
sqlite3* SQL;
bool SQlite(const char* sql, int(*callback)(void*, int, char**, char**) = NULL, void* a = NULL);
char *zErrMsg = nullptr;
std::mutex mutex;
// 检查字符串中是否包含小数点
bool containsDecimal(const std::string &str) {
for (char ch : str) {
if (ch == '.') {
return true;
}
}
return false;
}
// 根据字符串内容转换为 int 或 double
template<typename T>
T convert(const std::string &str) {
std::istringstream iss(str);
T value;
iss >> value;
if (iss.fail()) {
throw std::invalid_argument("Conversion failed.");
}
return value;
}
};
#endif

View File

@ -0,0 +1,106 @@
#ifndef STM32API_CCSTRING_H
#define STM32API_CCSTRING_H
#include "../../include/CCVector.hpp"
#include <stdio.h>
#define PC
#ifdef PC
#include <string>
#include "strstream"
#include "sstream"
using CCString = std::string;
using CCStream = std::strstream;
#else
class CCString
{
public:
CCString() = default;
CCString(const char* str);
CCString(const CCString& str);
CCString(CCVector<char> str);
//----------------------------------------------------------------
const char* c_str();
unsigned int length();
float to_float();
int to_int();
void append(char str);
void append(const char* str);
void append(CCString str);
void append(CCVector<char> str);
void clear();
//----------------------------------------------------------------
bool operator==(const char* str);
bool operator==(const CCString str);
bool operator!=(const char* str);
bool operator!=(const CCString& str);
//----------------------------------------------------------------
CCString operator+(const char* str);
void erase(int index,int len);
unsigned int find(char str);
unsigned int find(const char* str);
unsigned int find(CCString str);
void replace(int index,char str);
void replace(int index,const char* str);
void replace(int index,int index2, const char *str);
//----------------------------------------------------------------
#ifdef __JSON__
JSONObject to_json()
{
return JSONObject::Parse(c_str());
}
#endif
private:
CCVector<char> data;
void copy(const char* str);
void copy(char* str,const char* str2,int len);
void copy(char* str,CCVector<char> str2,int len);
int strlenth(const char* str);
};
namespace CCTools
{
inline CCString To_CCString(int index)
{
char str[100] = {0};
sprintf(str,"%d",index);
return str;
}
inline CCString To_CCString(float index)
{
char str[100] = {0};
sprintf(str,"%.5f",index);
return str;
}
inline CCString To_CCString(double index)
{
char str[100] = {0};
sprintf(str,"%lf",index);
return str;
}
template<typename T>
inline CCString To_CCString(const char* l,T num)
{
char str[100] = {0};
sprintf(str,l,num);
return str;
}
#ifdef __JSON__
inline CCString To_CCString(JSONObject a)
{
return "";
}
#endif
enum Error_type
{
Lengtherror = -1,
};
}
#endif
#endif

View File

@ -0,0 +1,145 @@
#ifndef DEMO_CCWEB_H
#define DEMO_CCWEB_H
#include "../../include/CCSocket.h"
#include "../../include/CCThread.h"
#include "functional"
#include <sys/stat.h>
#include "map"
#include "mutex"
#include "nlohmann/json.hpp"
#include "fstream"
#include "sstream"
#define UserMAX 20
#define BufferSize 4096
enum RequestProcess
{
RequestProcess_First,
RequestProcess_Header,
RequestProcess_Body,
};
struct HTTPRequestFile
{
std::string Name;
std::string Type;
std::vector<char> Buffer;
std::map<std::string,std::string> Headers;
bool Save(std::string Path) const;
};
struct HTTPRequest
{
unsigned int ID = 0;
std::string Method;
std::string Path;
std::string Version;
std::string Data;
std::string Buffer;
std::vector<char> Bufferstr;
std::map<std::string,std::string> Headers;
std::map<std::string,std::string> BodyData;
HTTPRequestFile FileData;
};
class CCWeb
{
private:
using RequestFunc = std::function<void(const HTTPRequest&,CCWeb*)>;
std::map<std::string,RequestFunc> RequestFun;
std::vector<std::string> PathSix;
bool PrintBool = false;
std::mutex mutexs;
std::string BUFFER;
public:
CCWeb() = default;
//----------------------------------------------------------------
HTTPRequest HTTPRequests;
//----------------------------------------------------------------
bool HTTPStart(const char * IP, int port);
bool SendResources(unsigned int ID, const char* Path, const char* Mode = "rb");
bool SendResourcesData(unsigned int ID, const char* Data);
bool SendData(unsigned int ID, const char* Data,const char* type = "text/plain");
std::string GetPath(const char* Path);
std::string GetMethod(const char* str);
std::string GetFileSuffix(const std::string& filePath);
std::string GetFileType(const std::string& str);
std::string GetData(std::string name,HTTPRequest request);
std::string FilterString(const char * str,char Begin,char End);
std::string GetRequestData(const char * str);
std::string GetIP(IPVX port = IPVX::IPV4);
std::string StrSplicing(const char *__restrict _format,...);
void HTTPStop();
void SetAddRootPath(const std::string& rootPath);
void SetPrint(bool print);
void SetRequestFunction(std::string RootPath,RequestFunc RFunc);
unsigned int GetFileSize(const char* path);
//----------------------------------------------------------------
template<typename Data>
std::string ReviseHTMLData(const char * Path, const char* Flags,Data&& data);
template<typename Data>
std::string ReviseData(const char * Date, const char* Flags,Data&& data);
template<class name>
name GetHTTPRequestData(const char * Date,std::string Request);
std::string GetHTTPRequestData(const char * Date,std::string Request);
std::string Getboundary(std::string& FileData);
//----------------------------------------------------------------
private:
std::string Filtration(const char * buf);
std::string FiltrationJson(const char *buf);
//----------------------------------------------------------------
CCSocket Server,Client[UserMAX] = { };
CCThread Threadappect,Thread[UserMAX] = { };
unsigned int ThreadCount = 0,lent = 0;
CC_Thread Appect();
CC_Thread ReadThread(unsigned int ID);
};
template<typename Data>
inline std::string CCWeb::ReviseHTMLData(const char *Path, const char *Flags, Data&& data)
{
std::string str,Flag = std::string("{{") + Flags + "}}";
std::ifstream file(Path,std::ios::in);
if (file.is_open())
{
char buf[BufferSize] = {0};
while (file.getline(buf,BufferSize))
{
str.append(buf);
memset(buf,'\000',BufferSize);
}
file.close();
}
else
{
return "Not found file";
}
size_t i = str.find(Flag);
if(i != std::string::npos)
{
str.replace(i,Flag.length(),data);
}
return str;
}
template<typename Data>
inline std::string CCWeb::ReviseData(const char *Date, const char *Flags, Data&& data)
{
std::string str = Date,Flag = std::string("{{") + Flags + "}}";
size_t i = str.find(Flag);
if(i != std::string::npos)
{
str.replace(i,Flag.length(),data);
}
return str;
}
#endif

View File

@ -0,0 +1,51 @@
#ifndef CCWeb_Servlet_H
#define CCWeb_Servlet_H
#pragma once
#include "CCSocket.h"
#include "../../include/CCJSONObject.h"
#include "../../include/CCThread.h"
#include "../../include/CCThreadPool.h"
#include "CCString.h"
#include "CCResponse.h"
#define Buffer_Max 1024
class CCWebServlet:public CCResponse
{
private:
using RequestFunc = std::function<void(CCRequest& ,CCResponse&)>;
std::map<std::string,RequestFunc> RequestFun;
CCString ServerIP;
CCSocket m_Socket;
int numThreads = 5,ListenMax = 50,RootLen = 0;
bool FlagRun = true;
CCThread m_Thread;
CCThreadPool m_ThreadPool;
std::vector<std::string> PathSix;
CORS CORSConfig;
std::mutex m_Mutex;
public:
public:
CCWebServlet() = default;
void SetThreadNumber(int headcount);
void SetWebServlet(CCString RootPath,RequestFunc RFunc);
void SetAddRootPath(const CCString& rootPath);
bool Sign() const;
bool Start(CCString IP,int port);
void Close();
void SetCorsConfig(CORS& cors);
private:
void ProcessRequest();
void ResponseData(CCSocket & socket);
};
#endif

View File

@ -0,0 +1,41 @@
#ifndef CC_Web_CORS_H
#define CC_Web_CORS_H
#include <vector>
#include "CCString.h"
#include "iostream"
class CORS
{
public:
CORS() = default;
void AddAllowOrigin(const CCString& Origin);
void AddHeader(const CCString& Key,const CCString& Value);
std::vector<CCString> GetAllowOrigin();
std::map<CCString,CCString> GetHeader();
private:
std::map<CCString,CCString> CORSA;
std::vector<CCString> AllowOrigin;
};
inline void CORS::AddAllowOrigin(const CCString& Origin) {
AllowOrigin.push_back(Origin);
}
inline void CORS::AddHeader(const CCString &Key, const CCString &Value) {
CORSA.insert(std::pair<CCString,CCString>(Key,Value));
}
inline std::vector<CCString> CORS::GetAllowOrigin() {
return AllowOrigin;
}
inline std::map<CCString,CCString> CORS::GetHeader() {
return CORSA;
}
#endif

View File

@ -0,0 +1,312 @@
#include "CCRequest.h"
#include <CCThread.h>
#include <utility>
CCString CCRequest::GetFileType(const CCString &str) {
std::string suffix = GetFileSuffix(str);
if(suffix == "html")
{
return "text/html";
}
else if(suffix == "css")
{
return "text/css";
}
else if(suffix == "js")
{
return "text/javascript";
}
else if(suffix == "png")
{
return "image/png";
}
else if(suffix == "jpg")
{
return "image/jpg";
}
else if(suffix == "jpeg")
{
return "image/jpeg";
}
else if(suffix == "gif")
{
return "image/gif";
}
else if(suffix == "ico")
{
return "image/x-icon";
}
else if(suffix == "svg")
{
return "image/svg+xml";
}
else if(suffix == "txt")
{
return "text/plain";
}
else if(suffix == "xml")
{
return "text/xml";
}
else if(suffix == "json")
{
return "application/json";
}
else if(suffix == "pdf")
{
return "application/pdf";
}
else if(suffix == "zip")
{
return "application/zip";
}
else
{
return suffix;
}
}
CCString CCRequest::GetFileSuffix(const CCString &filePath) {
size_t dotPosition = filePath.rfind('.'); // 从右向左查找最后一个'.'的位置
if (dotPosition == std::string::npos)
{
return ""; // 如果没有找到'.',则返回空字符串
}
return filePath.substr(dotPosition + 1); // 返回'.'之后的部分,即文件后缀名
}
unsigned int CCRequest::GetFileSize(const char *path) {
FILE *file = fopen(path, "rb");
if (file == nullptr) {
perror("Error opening file");
return 1;
}
fclose(file);
struct stat fileStat{};
if (stat(path, &fileStat) == 0)
{
return fileStat.st_size;
}
else
{
perror("Error getting file size");
return 0;
}
}
void CCRequest::SetBuffer(BufferReader &buffer) {
Buffer = buffer;
}
BufferReader CCRequest::GetReader() {
return Buffer;
}
JSON CCRequest::GetJson(const BufferReader& instr) {
try
{
return JSON::parse(instr.Body);
}
catch (const std::exception& e)
{
return nullptr;
}
}
BufferFile CCRequest::GetFile(BufferReader in) {
BufferFile File;
File.Buffer = ReaderFormData(std::move(in),File.Headers);
return File;
}
std::map<std::string, std::string> CCRequest::parseKeyValuePairs(const std::string &input) {
std::map<std::string, std::string> keyValuePairs;
size_t start = 0;
size_t end = 0;
while ((end = input.find('\r', start)) != std::string::npos) {
std::string line = input.substr(start, end - start);
size_t colonPos = line.find(':');
if (colonPos == std::string::npos) {
// 处理键值对
size_t eqPos = line.find('=');
if (eqPos != std::string::npos) {
std::string key = line.substr(0, eqPos);
size_t quoteStart = line.find('"', eqPos);
size_t quoteEnd = line.find('"', quoteStart + 1);
if (quoteStart != std::string::npos && quoteEnd != std::string::npos) {
std::string value = line.substr(quoteStart + 1, quoteEnd - quoteStart - 1);
keyValuePairs[key] = value;
}
}
} else {
// 处理以冒号分隔的键值对
std::string key = line.substr(0, colonPos);
std::string value = line.substr(colonPos + 2); // 跳过冒号和空格
keyValuePairs[key] = value;
}
start = end + 2; // 跳过 "\r\n"
}
return keyValuePairs;
}
void CCRequest::GetFormData(CCString &input, CCString &key, CCString &value) {
// 寻找等号的位置
size_t equalPos = input.find('=');
if (equalPos != std::string::npos) {
// 提取键(等号前的部分)
key = input.substr(0, equalPos);
key.erase(0, key.find_first_not_of(' ')); // 去除前导空格
key.erase(key.find_last_not_of(' ') + 1); // 去除尾随空格
// 寻找第一个双引号的位置
size_t startPos = input.find('"', equalPos);
if (startPos != std::string::npos) {
// 寻找最后一个双引号的位置
size_t endPos = input.find('"', startPos + 1);
if (endPos != std::string::npos) {
// 提取值(两个双引号之间的部分)
value = input.substr(startPos + 1, endPos - startPos - 1);
}
}
}
}
CCString CCRequest::GetFileDateHeader(BufferReader in, std::map<CCString, CCString> &map) {
CCString str = in.Body,A,B;
auto len = str.find("\r\n");
CCString Boundary = str.substr(0,len);
str.erase(0,len+2);
map["Boundary"] = Boundary;
std::stringstream ss(str);
ss >> A;
ss >> B;
len = A.length() + B.length();
A.erase(A.length()-1,A.length());
B.erase(B.length()-1,B.length());
map[A] = B;
str.erase(0,len+2);
GetFormData(str,A,B);
map[A] = B;
len = A.length() + B.length();
str.erase(0,len + 5);
len = str.find("\r\n\r\n");
CCString str2 = str.substr(0,len+4);
str.erase(0,len+4);
auto m = parseKeyValuePairs(str2);
for (const auto& i : m) {
map[i.first] = i.second;
}
return str;
}
std::vector<char> CCRequest::ReaderFormData(BufferReader in, std::map<CCString, CCString> &map) {
std::vector<char> data;
CCString str = GetFileDateHeader(std::move(in),map);
CCString B = "\r\n" + map["Boundary"] + "--\r\n";
auto len = str.find(B);
if(len != std::string::npos){
for (int i = 0; i < len; ++i) {
data.push_back(str[i]);
}
}
return data;
}
CCString CCRequest::GetParameter(CCString string) {
CCString str,f = CCString(string + "=");
auto len = Buffer.Body.length();
int pos = 0,A = f.length();
for (int i = 0; i < len; ++i) {
CCString B = Buffer.Body.substr(i,A);
if(f == B){
pos = i + A;
break;
}
}
for (int i = pos; i < len; ++i) {
if(Buffer.Body[i] != '&'){
str += Buffer.Body[i];
}
else{
break;
}
}
return str;
}
OutPutStream CCRequest::GetWiter() {
return this->Socket;
}
CCRequest::CCRequest(CCSocket &sc) {
this->Socket = sc;
}
void OutPutStream::SetMethod(MethodType method) {
if(method == MethodType_GET){
this->SendHeaders["Method"] = "GET";
}
if(method == MethodType_POST){
this->SendHeaders["Method"] = "POST";
}
if(method == MethodType_PUT){
this->SendHeaders["Method"] = "PUT";
}
if(method == MethodType_DELETE){
this->SendHeaders["Method"] = "DELETE";
}
if(method == MethodType_OPTIONS){
this->SendHeaders["Method"] = "OPTIONS";
}
if(method == MethodType_HEAD){
this->SendHeaders["Method"] = "HEAD";
}
}
void OutPutStream::AddHeader(const CCString &Key, const CCString &Value) {
this->SendHeaders[Key] = Value;
}
void OutPutStream::SetHost(const CCString &host) {
this->RPath = host;
}
void OutPutStream::SetBufferBody(CCString body) {
this->RBody = body;
}
OutPutStream::OutPutStream(CCSocket &sc) {
this->Socket = sc;
}
void OutPutStream::Send() {
CCString str = this->SendHeaders["Method"] + " " + this->RPath + " HTTP/1.1\r\n";
str.append("Server:HTTP->CCWeb->OK\r\n");
for (int i = 0; i < this->SendHeaders.size(); ++i) {
CCString A = this->SendHeaders.begin()->first+":"+this->SendHeaders.begin()->second+"\r\n";
str.append(A);
}
str.append("\r\n");
str.append(this->RBody);
Socket.Sendbyte(str.c_str(),(int)str.length());
}
bool BufferFile::Save(const CCString &Path) {
CCFile file = CCFile(Path.c_str(),CC::ios::wb);
if(file.IsOpen()){
file.Write((char*)Buffer.data(),Buffer.size());
Threading::Sleep(1000*16);
file.Close();
return true;
}
return false;
}
CCString BufferFile::GetFileName() {
return this->Headers["filename"];
}

View File

@ -0,0 +1,181 @@
#include "CCResponse.h"
CCResponse::CCResponse(CCSocket &socket,CORS& cors) {
this->Client = socket;
Cors = cors;
}
HTTPResponse CCResponse::GetWiter()
{
return HTTPResponse(Client,Cors);
}
void HTTPResponse::HtmlTextWrite(const CCString& str) {
this->Write(str, "text/html");
}
HTTPResponse::HTTPResponse(CCSocket &socket,CORS& cors) {
Client = socket;
CORSConfig = cors;
}
void HTTPResponse::Write(const CCString& str, const char *type) {
char buf[200] = {0};
Client.Send("HTTP/1.1 200 OK\r\n");
Client.Send("Server:HTTP->CCWebServlet->OK\r\n");
CCString Origin;
auto len = CORSConfig.GetAllowOrigin().size();
std::map<CCString,CCString> headers = CORSConfig.GetHeader();
for (int i = 0;i < len;i++){
CCString string = CORSConfig.GetAllowOrigin()[i];
Origin.append(string);
if(i != len - 1)
{
Origin.append(",");
}
}
for (const auto& i : headers) {
sprintf(buf, "%s:%s\r\n",i.first.c_str(),i.second.c_str());
Client.Send(buf);
}
if(Origin.empty())
{
Origin = "null";
}
sprintf(buf, "Access-Control-Allow-Origin:%s\r\n",Origin.c_str());
Client.Send(buf);
Client.Send("Access-Control-Allow-Headers:Content-Type, X-Requested-With\r\n");
Client.Send("Access-Control-Allow-Methods:GET,POST,PUT,DELETE,OPTIONS\r\n");
try {
if(!JSON::parse(str).empty())
{
type = "application/json";
}
}
catch (const std::exception& e) {}
sprintf(buf, "Content-type:%s; charset=utf-8\r\n",type);
Client.Send(buf);
sprintf(buf, "Content-Length:%zu\r\n", str.length());
Client.Send(buf);//Content-Length:
Client.Send("\r\n");
Client.Send(str.c_str());
//Client.Send("\r\n\r\n");
}
bool HTTPResponse::HtmlWrite(const CCString &str) {
return SendResources(str.c_str());
}
bool HTTPResponse::SendResources(const char *Path, const char *Mode) {
Mutex.lock();
FILE *file = fopen(Path, Mode); // 替换为你的文件名
if (file == nullptr)
{
Mutex.unlock();
return false;
}
Client.Send("HTTP/1.1 200 OK\r\n");
Client.Send("Server:HTTP->CCWeb->OK\r\n");
char buf[50] = {0};
sprintf(buf, "Content-type:%s\r\n", GetFileType(Path).c_str());
Client.Send(buf);
sprintf(buf, "Content-Length:%d\r\n", GetFileSize(Path));
Client.Send(buf);//Content-Length:
Client.Send("\r\n");
int cout = 0;
char bufs[4096] = { 0 };
int fpId = -1;
struct stat st;
fpId = fileno( file );
if( fstat( fpId ,&st) == -1 )
{
Mutex.unlock();
return false;
}
while (!feof(file))
{
int ret = fread(bufs,sizeof(char),sizeof bufs,file);
Client.Send(bufs,sizeof bufs,0);
cout += ret;
}
fclose(file);
Mutex.unlock();
return true;
}
void HTTPResponse::Send(const CCString &string) {
Client.Send(string.c_str());
}
void HTTPResponse::ResponseOK() {
char buf[200] = {0};
Client.Send("HTTP/1.1 200 OK\r\n");
Client.Send("Server:HTTP->CCWeb->OK\r\n");
CCString Origin;
auto len = CORSConfig.GetAllowOrigin().size();
std::map<CCString,CCString> headers = CORSConfig.GetHeader();
for (int i = 0;i < len;i++){
CCString string = CORSConfig.GetAllowOrigin()[i];
Origin.append(string);
if(i != len - 1)
{
Origin.append(",");
}
}
if(Origin.empty())
{
Origin = "null";
}
sprintf(buf, "Access-Control-Allow-Origin:%s\r\n",Origin.c_str());
Client.Send(buf);
Client.Send("Access-Control-Allow-Headers:*, X-Requested-With\r\n");
Client.Send("Access-Control-Allow-Methods:GET,POST,PUT,DELETE,OPTIONS\r\n");
Client.Send("\r\n");
}
bool HTTPResponse::WriteFile(const CCString &Path) {
Mutex.lock();
FILE *file = fopen(Path.c_str(), "rb"); // 替换为你的文件名
if (file == NULL)
{
Mutex.unlock();
return false;
}
Client.Send("HTTP/1.1 200 OK\r\n");
Client.Send("Server:HTTP->CCWeb->OK\r\n");
char buf[50] = {0};
sprintf(buf, "Content-type:text/plain\r\n");
Client.Send(buf);
memset(buf,0,sizeof buf);
CCFile file2 = CCFile(Path.c_str(),CC::ios::rb,false);
sprintf(buf, "Content-Disposition: attachment; filename=\"%s\"\r\n",file2.GetFileInfo().Name.c_str());
Client.Send(buf);
memset(buf,0,sizeof buf);
sprintf(buf, "Content-Length:%ld\r\n", file2.GetFileInfo().Size);
Client.Send(buf);//Content-Length:
Client.Send("\r\n");
int cout = 0;
char bufs[4096] = { 0 };
int fpId = -1;
struct stat st;
fpId = fileno( file );
if( fstat( fpId ,&st) == -1 )
{
Mutex.unlock();
return false;
}
while (!feof(file))
{
int ret = fread(bufs,sizeof(char),sizeof bufs,file);
Client.Send(bufs,sizeof bufs,0);
cout += ret;
}
fclose(file);
Mutex.unlock();
return true;
}

View File

@ -0,0 +1,86 @@
#include "CCSQLite3.h"
CCSQLite3::CCSQLite3(CCString Path) {
Open(Path);
}
bool CCSQLite3::Open(CCString Path) {
int ret = sqlite3_open(Path.c_str(),&SQL);
if (ret)
{
return false;
}
return true;
}
bool CCSQLite3::SqlUpdate(CCString sql) {
return SQlite(sql.c_str(), nullptr, nullptr);
}
CCResultSet CCSQLite3::SqlQuery(CCString sql) {
char** pResult;
int nRow;
int nCol = 0;
char* errmsg = nullptr;
CCResultSet Row_Col;
int nResult = sqlite3_get_table(SQL, sql.c_str(), &pResult, &nRow, &nCol, &errmsg);
if (nResult != SQLITE_OK)
{
sqlite3_free(errmsg);
return { };
}
Row_Col.Col = nCol;
Row_Col.Row = nRow;
int nIndex = nCol;
for (int i = 0; i < nRow; i++)
{
JSON strCol;
for (int j = 0; j < nCol; j++)
{
bool is_int = containsDecimal(pResult[nIndex]);
try {
// 根据是否有小数点选择转换类型
if (is_int) {
auto result = convert<double>(pResult[nIndex]);
strCol[pResult[j]] = result;
} else {
int result = convert<int>(pResult[nIndex]);
strCol[pResult[j]] = result;
}
}
catch (std::exception &e){
strCol[pResult[j]] = pResult[nIndex];
}
++nIndex;
}
Row_Col.Data.push_back(strCol);
}
sqlite3_free_table(pResult);
Row_Col.Flag = true;
return Row_Col;
}
bool CCSQLite3::Close(){
return sqlite3_close(SQL) != 0;
}
bool CCSQLite3::SQlite(const char* sql,int(*callback)(void *,int,char**,char**),void* a){
mutex.lock();
int rc = sqlite3_exec(SQL, sql, callback, a, &zErrMsg);
if (rc != SQLITE_OK)
{
sqlite3_free(zErrMsg);
mutex.unlock();
return false;
}
else
{
mutex.unlock();
return true;
}
}
CCString CCSQLite3::GetError() {
return zErrMsg;
}

View File

@ -0,0 +1,308 @@
#include <cassert>
#include "CCString.h"
#define PC
#ifdef PC
#else
void CCString::copy(const char* str)
{
data.clear();
for (int i = 0; i < strlenth(str); i++)
{
data.push_back(str[i]);
}
}
int CCString::strlenth(const char* str)
{
int count = 0;
while (str[count] != '\0')
{
count++;
}
return count;
}
CCString::CCString(const char *str)
{
data.clear();
for (int i = 0; i < strlenth(str); i++)
{
data.push_back(str[i]);
}
}
CCString::CCString(const CCString &str)
{
data = str.data;
}
CCString::CCString(CCVector<char> str)
{
data = str;
}
const char *CCString::c_str()
{
char* c = (char*)malloc(data.size());
for (int i = 0; i < data.size();i++)
{
c[i] = '\0';
}
for (int i = 0; i < data.size(); ++i)
{
c[i] = data[i];
}
c[data.size()] = '\0';
return c;
}
unsigned int CCString::length()
{
return data.size();
}
float CCString::to_float()
{
char* str = (char*)malloc(data.size());
copy(str,data,data.size());
str[data.size()] = '\0';
char *endptr; // 用于存储解析结束的位置
double d_value = strtod(str, &endptr); // 将字符串转换为double
if (endptr == str || *endptr != '\0')
{
return 0;
}
else
{
float f_value = (float)d_value; // 将double转换为float
return f_value;
}
}
int CCString::to_int()
{
char* str = (char*)malloc(data.size());
copy(str,data,data.size());
str[data.size()] = '\0';
char *endptr; // 用于存储解析结束的位置
double d_value = strtod(str, &endptr); // 将字符串转换为double
if (endptr == str || *endptr != '\0')
{
return 0;
}
else
{
int f_value = (float)d_value; // 将double转换为float
return f_value;
}
}
void CCString::append(const char str)
{
data.push_back(str);
}
void CCString::clear()
{
data.clear();
}
void CCString::append(const char *str)
{
for (int i = 0; i < strlenth(str); i++)
{
data.push_back(str[i]);
}
}
void CCString::append(CCString str)
{
for (int i = 0; i < str.data.size(); i++)
{
data.push_back(str.data[i]);
}
}
void CCString::append(CCVector<char> str)
{
for (int i = 0; i < str.size(); i++)
{
data.push_back(str[i]);
}
}
void CCString::copy(char *str, const char *str2, int len)
{
for (int i = 0; i < len; i++)
{
str[i] = str2[i];
}
}
void CCString::copy(char *str, CCVector<char> str2, int len)
{
for (int i = 0; i < len; i++)
{
str[i] = str2[i];
}
}
bool CCString::operator==(const char *str)
{
if(data.size() != strlenth(str))
{
return false;
}
for (int i = 0; i < strlenth(str); i++)
{
if (data[i] != str[i])
{
return false;
}
}
return true;
}
bool CCString::operator==(CCString str)
{
if(data.size() != str.length())
{
return false;
}
for (int i = 0; i < str.length(); i++)
{
if (data[i] != str.data[i])
{
return false;
}
}
return true;
}
bool CCString::operator!=(const char *str)
{
return !this->operator==(str);
}
bool CCString::operator!=(const CCString &str)
{
return !this->operator==(str);
}
CCString CCString::operator+(const char *str)
{
CCString newStr(*this);
newStr.append(str);
return newStr;
}
void CCString::erase(int index, int len)
{
data.erase(index, len);
}
unsigned int CCString::find(char str)
{
for (int i = 0; i < data.size(); i++)
{
if (data[i] == str)
{
return i;
}
}
return -1;
}
unsigned int CCString::find(const char *str)
{
for (int i = 0; i < data.size(); i++)
{
if (data[i] == str[0])
{
bool flag = true;
for (int j = 0; j < strlenth(str); j++)
{
if (data[i + j] != str[j])
{
flag = false;
break;
}
}
if (flag)
{
return i;
}
}
}
return -1;
}
unsigned int CCString::find(CCString str)
{
for (int i = 0; i < data.size(); i++)
{
if (data[i] == str.data[0])
{
bool flag = true;
for (int j = 0; j < str.length(); j++)
{
if (data[i + j] != str.data[j])
{
flag = false;
break;
}
}
if (flag)
{
return i;
}
}
}
return -1;
}
void CCString::replace(int index, char str)
{
data.revise(index,str);
}
void CCString::replace(int index, const char *str)
{
CCVector<char> newStr;
for (int i = 0; i < index; i++)
{
newStr.push_back(data[i]);
}
for (int i = 0; i < strlenth(str); i++)
{
newStr.push_back(str[i]);
}
for (int i = index + strlenth(str); i < data.size(); i++)
{
newStr.push_back(data[i]);
}
data = newStr;
}
void CCString::replace(int index,int index2, const char *str)
{
CCVector<char> newStr;
for (int i = 0; i < index; i++)
{
newStr.push_back(data[i]);
}
for (int i = 0; i < strlenth(str); i++)
{
newStr.push_back(str[i]);
}
for (int i = index2; i < data.size(); i++)
{
newStr.push_back(data[i]);
}
data = newStr;
}
#endif

743
SDK/CCServlet/src/CCWeb.cpp Normal file
View File

@ -0,0 +1,743 @@
#include "CCWeb.h"
#include <stdarg.h>
std::string CCWeb::GetMethod(const char* str)
{
char buf[10] = { 0 };
for (int i = 0; i < strlen(str); ++i)
{
if(str[i] != ' ')
{
buf[i] = str[i];
}
else
{
break;
}
}
return buf;
}
std::string CCWeb::GetPath(const char* Path)
{
bool ret = false;
char buf[50] = { 0 };
int len = 0;
for (int i = 0; i < strlen(Path); ++i)
{
if(Path[i] == '/' && !ret)
{
ret = true;
}
else if(ret)
{
if(Path[i] != ' ')
{
buf[len] = Path[i];
++len;
}
else
{
break;
}
}
}
return buf;
}
bool CCWeb::SendResources(unsigned int ID, const char *Path, const char *Mode)
{
FILE *file = fopen(Path, Mode); // 替换为你的文件名
if (file == NULL)
{
return false;
}
Client[ID].Send("HTTP/1.1 200 OK\r\n");
Client[ID].Send("Server:HTTP->CCWeb->OK\r\n");
char buf[50] = {0};
sprintf(buf, "Content-type:%s\r\n", GetFileType(Path).c_str());
Client[ID].Send(buf);
sprintf(buf, "Content-Length:%d\r\n", GetFileSize(Path));
Client[ID].Send(buf);//Content-Length:
Client[ID].Send("\r\n");
int cout = 0;
char bufs[4096] = { 0 };
int fpId = -1;
struct stat st;
fpId = fileno( file );
if( fstat( fpId ,&st) == -1 )
{
return false;
}
while (!feof(file))
{
int ret = fread(bufs,sizeof(char),sizeof bufs,file);
Client[ID].Send(bufs,sizeof bufs,0);
cout += ret;
}
//Client[ID].Send("\r\n",sizeof "\r\n",0);
if(PrintBool)
{
printf("Send to Clent len:%d\r\n",cout);
}
fclose(file);
return true;
}
bool CCWeb::HTTPStart(const char *IP, int port)
{
this->SetAddRootPath("");
lent = PathSix.size();
Server.Socket(IPVX::IPV4,TORU::TCP);
if(!Server.Bind(IP,port))
{
return false;
}
if(!Server.Listen(UserMAX))
{
return false;
}
Threadappect.SetThread(&CCWeb::Appect,this);
Threadappect.Start();
return true;
}
CC_Thread CCWeb::Appect()
{
while (Threadappect.Sign())
{
Client[ThreadCount] = Server.Accept();
Thread[ThreadCount].SetThread(&CCWeb::ReadThread,this,ThreadCount);
Thread[ThreadCount].Start();
ThreadCount++;
if(ThreadCount >= UserMAX)
{
ThreadCount = 0;
}
}
std::cout << "END" << std::endl;
return Threadappect.Stop();
}
CC_Thread CCWeb::ReadThread(unsigned int ID)
{
mutexs.lock();
bool ReadFlag = false;
ByteHander len = BufferSize;
char Buffer[BufferSize] = {0};
HTTPRequests.Bufferstr.clear();
HTTPRequests.BodyData.clear();
HTTPRequests.Headers.clear();
HTTPRequests.FileData.Buffer.clear();
HTTPRequests.FileData.Headers.clear();
while (len >= BufferSize)
{
len = Client[ID].RecvData(Buffer, sizeof(Buffer));
for (int i = 0; i < len; ++i) {
HTTPRequests.Bufferstr.push_back(Buffer[i]);
}
memset(Buffer,0, BufferSize);
}
std::string RecvMessage(HTTPRequests.Bufferstr.begin(), HTTPRequests.Bufferstr.end());
HTTPRequests.Bufferstr.clear();
if (len > 0)
{
if (PrintBool)
{
std::cout << Buffer << std::endl;
std::cout<< "ThreadID:" << ID << std::endl;
}
RequestProcess Stuart = RequestProcess_First;
while(true)
{
auto strlen = RecvMessage.find("\r\n");
std::istringstream stream(RecvMessage.substr());
if(strlen == 0)
{
Stuart = RequestProcess_Body;
}
if(strlen != std::string::npos)
{
if(Stuart == RequestProcess_First)
{
stream >> HTTPRequests.Method;
stream >> HTTPRequests.Path;
stream >> HTTPRequests.Version;
RecvMessage.erase(0,strlen + 2);
Stuart = RequestProcess_Header;
}
else if(Stuart == RequestProcess_Header)
{
std::string Key,Value;
stream >> Key;
stream >> Value;
Key.erase(remove(Key.begin(),Key.end(),':'),Key.end());
HTTPRequests.Headers.insert(std::pair<std::string,std::string>(Key,Value));
RecvMessage.erase(0,strlen + 2);
}
else if(Stuart == RequestProcess_Body)
{
if(HTTPRequests.Headers["Content-Type"] == "multipart/form-data;")
{
auto lenstr = HTTPRequests.Headers["Content-Length"];
auto FileSize = atoi(lenstr.c_str());
while (FileSize > 0)
{
len = Client[ID].RecvData(Buffer, sizeof(Buffer));
for (int i = 0; i < len; ++i) {
HTTPRequests.Bufferstr.push_back(Buffer[i]);
}
memset(Buffer,0, BufferSize);
FileSize = FileSize - len;
}
std::string FileData(HTTPRequests.Bufferstr.begin(), HTTPRequests.Bufferstr.end());
auto END = Getboundary(FileData);
std::string name,filename;
strlen = FileData.find("name=\"");
for(int i = strlen + 6;i < FileData.length(); i++)
{
if(FileData[i] != '\"')
{
name += FileData[i];
}
else
{
break;
}
}
HTTPRequests.FileData.Headers.insert(std::pair<std::string,std::string>("name",name));
strlen = FileData.find("filename=\"");
for(int i = strlen + 10;i < FileData.length(); i++)
{
if(FileData[i] != '\"')
{
filename += FileData[i];
}
else
{
break;
}
}
HTTPRequests.FileData.Headers.insert(std::pair<std::string,std::string>("filename",filename));
while(true)
{
strlen = FileData.find("\r\n");
std::string Key,Value;
std::istringstream stra(FileData.substr());
stra >> Key;
stra >> Value;
Key.erase(remove(Key.begin(),Key.end(),':'),Key.end());
HTTPRequests.FileData.Headers.insert(std::pair<std::string,std::string>(Key,Value));
FileData.erase(0,strlen + 2);
if(strlen == 0)
{
break;
}
}
strlen = FileData.find("\r\n" + END + "--");
for (int i = 0; i < strlen; ++i) {
HTTPRequests.FileData.Buffer.push_back(FileData[i]);
}
HTTPRequests.FileData.Name = HTTPRequests.FileData.Headers["filename"];
HTTPRequests.FileData.Type = HTTPRequests.FileData.Headers["name"];
break;
}
else if(HTTPRequests.Headers["Content-Type"] == "application/json")
{
}
else
{
std::string str;
stream >> str;//"username=admin&password=123456"
while(true)
{
strlen = str.find('&');
std::string Key,Value;
bool FA = false,ENDF = false;
if(strlen == std::string::npos)
{
strlen = str.length();
ENDF = true;
}
for (int i = 0; i < strlen; ++i)
{
if(str[i] != '=')
{
if(FA)
{
Value += str[i];
}
else
{
Key += str[i];
}
}
else
{
FA = true;
}
}
HTTPRequests.BodyData.insert(std::pair<std::string,std::string>(Key,Value));
str.erase(0,strlen + 1);
if(ENDF)
{
break;
}
}
break;
}
}
}
else
{
break;
}
}
HTTPRequests.ID = ID;
if (HTTPRequests.Method == "GET" || HTTPRequests.Method == "POST" || HTTPRequests.Method == "PUT")
{
std::map<std::string, RequestFunc>::iterator t;
for (t = RequestFun.begin(); t != RequestFun.end(); t++)
{
if (t->first == HTTPRequests.Path)
{
t->second(HTTPRequests, this);
ReadFlag = false;
break;
}
else
{
ReadFlag = true;
}
}
if (ReadFlag)
{
bool da = false;
for (int i = 0; i < lent; ++i)
{
if (this->SendResources(ID, std::string(PathSix[i] + HTTPRequests.Path).c_str()))
{
da = true;
break;
}
}
if (!da)
{
char bufsa[100] = {0};
sprintf(bufsa, "无法打开文件%s\n", HTTPRequests.Path.c_str());
perror(bufsa);
}
}
}
}
else
{
Thread[ID].Stop();
}
mutexs.unlock();
Client[ID].Close();
return Thread[ID].Stop();
}
std::string CCWeb::GetFileSuffix(const std::string& filePath)
{
size_t dotPosition = filePath.rfind('.'); // 从右向左查找最后一个'.'的位置
if (dotPosition == std::string::npos)
{
return ""; // 如果没有找到'.',则返回空字符串
}
return filePath.substr(dotPosition + 1); // 返回'.'之后的部分,即文件后缀名
}
std::string CCWeb::GetFileType(const std::string &str)
{
std::string suffix = GetFileSuffix(str);
if(suffix == "html")
{
return "text/html";
}
else if(suffix == "css")
{
return "text/css";
}
else if(suffix == "js")
{
return "text/javascript";
}
else if(suffix == "png")
{
return "image/png";
}
else if(suffix == "jpg")
{
return "image/jpg";
}
else if(suffix == "jpeg")
{
return "image/jpeg";
}
else if(suffix == "gif")
{
return "image/gif";
}
else if(suffix == "ico")
{
return "image/x-icon";
}
else if(suffix == "svg")
{
return "image/svg+xml";
}
else if(suffix == "txt")
{
return "text/plain";
}
else if(suffix == "xml")
{
return "text/xml";
}
else if(suffix == "json")
{
return "application/json";
}
else if(suffix == "pdf")
{
return "application/pdf";
}
else if(suffix == "zip")
{
return "application/zip";
}
else
{
return suffix;
}
}
void CCWeb::SetAddRootPath(const std::string& rootPath)
{
PathSix.push_back(rootPath);
}
void CCWeb::SetPrint(bool print)
{
PrintBool = print;
}
std::string CCWeb::Filtration(const char *buf)
{
char Date[BufferSize] = {0};
std::string buffer;
bool Flag = false;
int len = 0;
std::string le = buf;
auto d = le.length();
for (int i = 0; i < d; ++i)
{
if(buf[i] == '\r' && buf[i+1] == '\n' && buf[i+2] == '\r' && !Flag)
{
i = i+2;
Flag = true;
}
else if(Flag && buf[i] != '\0')
{
Date[len] = buf[i];
len++;
if(len == sizeof Date)
{
buffer.append(Date);
memset(Date,'\000',BufferSize);
len = 0;
}
}
}
buffer.append(Date);
return buffer;
}
std::string CCWeb::FiltrationJson(const char *buf)
{
char Date[BufferSize] = {0};
std::string buffer;
bool Flag = false;
int len = 0;
std::string le = buf;
auto d = le.length();
for (int i = 0; i < d; ++i)
{
if(buf[i] == '\r' && buf[i+1] == '\n' && buf[i+2] == '\r' && !Flag)
{
i = i+2;
Flag = true;
}
else if(Flag)
{
Date[len] = buf[i];
if(Date[len] == '}')
{
Date[len+1] = '\0';
buffer.append(Date);
break;
}
len++;
if(len == sizeof Date)
{
buffer.append(Date);
len = 0;
}
}
}
return buffer;
}
std::string CCWeb::GetData(std::string name, HTTPRequest request)
{
const HTTPRequest Date = request;
for(auto i : Date.BodyData)
{
if(i.first == name)
{
return i.second;
}
}
return "NO_Data";
}
std::string CCWeb::FilterString(const char *str, char Begin, char End)
{
char Date[BufferSize] = {0};
bool Flag = false;
int len = 0;
for (int i = 0; i < strlen(str); ++i)
{
if(str[i] == Begin && !Flag)
{
Flag = true;
}
if(Flag)
{
if(str[i] != End)
{
Date[len] = str[i];
len++;
}
else
{
break;
}
}
}
return Date;
}
void CCWeb::SetRequestFunction(std::string RootPath, RequestFunc RFunc)
{
RequestFun.insert(std::pair<std::string, RequestFunc>(RootPath, RFunc));
}
void CCWeb::HTTPStop()
{
Threadappect.Stop();
Server.Close();
for (int i = 0; i < ThreadCount; ++i)
{
Thread[i].Stop();
CCSocket sc = {};
if(Client[i] != sc)
{
Client[i].Close();
}
}
//Threading::Sleep(1000*5000);
ThreadCount = 0;
}
std::string CCWeb::GetIP(IPVX port)
{
return Server.GetlocadIP(port).c_str();
}
std::string CCWeb::GetRequestData(const char * str)
{
char Date[BufferSize] = {0};
bool Flag = false;
int len = 0;
auto da = strlen(str);
for (int i = 0; i < da; ++i)
{
if(str[i] == '7' && str[i+1] == 'B' && str[i+2] == '%' && str[i+3] == '7' && str[i+4] == 'B' && !Flag)
{
Flag = true;
i = i+4;
}
else if(Flag)
{
if(str[i] != '%')
{
Date[len] = str[i];
len++;
}
else
{
break;
}
}
}
return Date;
}
bool CCWeb::SendResourcesData(unsigned int ID, const char *Data)
{
Client[ID].Send("HTTP/1.1 200 OK\r\n");
Client[ID].Send("Server:HTTP->CCWeb->OK\r\n");
char buf[50] = {0};
sprintf(buf, "Content-type:text/html\r\n");
Client[ID].Send(buf);
sprintf(buf, "Content-Length:%d\r\n", (unsigned int)strlen(Data));
Client[ID].Send(buf);//Content-Length:
Client[ID].Send("\r\n");
Client[ID].Send(Data);
//Client[ID].Send("\r\n");
return true;
}
unsigned int CCWeb::GetFileSize(const char *Path)
{
FILE *file = fopen(Path, "rb");
if (file == nullptr) {
perror("Error opening file");
return 1;
}
fclose(file);
struct stat fileStat{};
if (stat(Path, &fileStat) == 0)
{
return fileStat.st_size;
}
else
{
perror("Error getting file size");
return 0;
}
}
std::string CCWeb::StrSplicing(const char * format,...)
{
char buf[BufferSize] = {0};
va_list args;
va_start(args, format);
int l = vsnprintf(buf, sizeof(buf), format, args);
if (l < 0 || l >= sizeof(buf)) {
return "ERROR";
}
va_end(args);
return buf;
}
bool CCWeb::SendData(unsigned int ID, const char *Data,const char* type)
{
Client[ID].Send("HTTP/1.1 200 OK\r\n");
Client[ID].Send("Server:HTTP->CCWeb->OK\r\n");
char buf[50] = {0};
sprintf(buf, "Content-type:%s; charset=utf-8\r\n",type);
Client[ID].Send(buf);
sprintf(buf, "Content-Length:%zu\r\n", strlen(Data));
Client[ID].Send(buf);//Content-Length:
Client[ID].Send("\r\n");
Client[ID].Send(Data);
//Client[ID].Send("\r\n");
return true;
}
template<class name>
name CCWeb::GetHTTPRequestData(const char * Date,std::string Request)
{
std::string Data = Date, RequestData;
auto len = Data.find(Request);
bool f = false;
for (int i = len; i < Data.length(); ++i) {
if(Data[i] == ' ' && !f)
{
f = true;
}
else if(f)
{
if(Data[i] != '\r')
{
RequestData += Data[i];
}
else
{
break;
}
}
}
name n;
std::istringstream ss(RequestData);
ss >> n;
return n;
}
std::string CCWeb::GetHTTPRequestData(const char * Date,std::string Request)
{
std::string Data = Date, RequestData;
auto len = Data.find(Request);
bool f = false;
for (int i = len; i < Data.length(); ++i) {
if(Data[i] == ' ' && !f)
{
f = true;
}
else if(f)
{
if(Data[i] != '\r')
{
RequestData += Data[i];
}
else
{
break;
}
}
}
return RequestData;
}
std::string CCWeb::Getboundary(std::string& FileData)
{
auto len = FileData.find("\r\n");
std::string str;
for(int i = 0; i < len; ++i)
{
str += FileData[i];
}
FileData.erase(0,len + 2);
return str;
}
bool HTTPRequestFile::Save(std::string Path) const
{
std::ofstream file(Path,std::ios::out|std::ios::binary); // 如果文件不存在,则创建它
// 检查文件是否成功打开
if (!file.is_open()) {
std::cerr << "无法打开文件" << std::endl;
return false;
}
std::string str(Buffer.begin(),Buffer.end());
file.write(str.c_str(),str.size());
// 关闭文件
file.close();
return true;
}

View File

@ -0,0 +1,154 @@
#include "CCWebServlet.h"
bool CCWebServlet::Start(CCString IP,int port){
FlagRun = true;
RootLen = this->PathSix.size();
m_Socket.Socket(IPVX::IPV4,TORU::TCP);
m_Socket.SetSocketNonBlocking();
m_ThreadPool.SetThreadTimeout(1000 * 16);
m_ThreadPool.InitStart(numThreads);
ServerIP = IP;
if(!m_Socket.Bind(ServerIP.c_str(), port))
{
return false;
}
if(!m_Socket.Listen(ListenMax))
{
return false;
}
m_Thread.SetThread(&CCWebServlet::ProcessRequest, this);
m_Thread.Start();
return true;
}
void CCWebServlet::ProcessRequest(){
while (m_Thread.Sign()){
CCSocket client = m_Socket.Accept();
if(client.GetHost().Port != 0){
m_ThreadPool.AddTask(&CCWebServlet::ResponseData, this, client);
}
}
}
void CCWebServlet::ResponseData(CCSocket &socket){
std::vector<char> data;
while (true){
char buffer[Buffer_Max] = {0};
if(socket.IsDataAvailable()){
auto len = socket.RecvData(buffer,Buffer_Max);
if(len > 0){
for (int i = 0; i < len; ++i){
data.push_back(buffer[i]);
}
}
else{
break;
}
}
else{
break;
}
}
CCString RecvMessage(data.begin(), data.end());
data.clear();
RequestProcess Stuart = RequestProcess_First;
auto strlen = RecvMessage.find("\r\n");
std::istringstream stream(RecvMessage.substr());
CCRequest HTTPRequests(socket);
BufferReader A;
CCResponse HTTPResponse(socket,CORSConfig);
while (true){
auto strlen = RecvMessage.find("\r\n");
std::istringstream stream(RecvMessage.substr());
if(strlen == 0)
{
Stuart = RequestProcess_Body;
}
if(strlen != std::string::npos) {
if (Stuart == RequestProcess_First) {
stream >> A.Method;
stream >> A.Path;
auto l = A.Path.find('?');
auto la = A.Path.length();
if(l > 0 && l != std::string::npos && A.Method=="GET"){
RecvMessage.append(A.Path.substr(l, la));
A.Path = A.Path.substr(0, l);
}
stream >> A.Version;
RecvMessage.erase(0, strlen + 2);
Stuart = RequestProcess_Header;
} else if (Stuart == RequestProcess_Header) {
std::string Key, Value;
stream >> Key;
stream >> Value;
Key.erase(remove(Key.begin(), Key.end(), ':'), Key.end());
HTTPRequests.Headers.insert(std::pair<std::string, std::string>(Key, Value));
RecvMessage.erase(0, strlen + 2);
}
else
{
RecvMessage.erase(0, strlen + 2);
A.Body = RecvMessage;
HTTPRequests.SetBuffer(A);
break;
}
}
}
if(A.Method == "OPTIONS"){
HTTPResponse.GetWiter().ResponseOK();
}
else{
auto it = RequestFun[HTTPRequests.GetReader().Path];
if(it)
{
it(HTTPRequests, HTTPResponse);
}
else
{
bool da = false;
for (int i = 0; i < RootLen; ++i)
{
if (HTTPResponse.GetWiter().HtmlWrite(std::string(PathSix[i] + HTTPRequests.GetReader().Path).c_str()))
{
da = true;
break;
}
}
if (!da)
{
char bufsa[100] = {0};
sprintf(bufsa, "无法打开文件%s\n", HTTPRequests.GetReader().Path.c_str());
perror(bufsa);
}
}
}
socket.Close();
}
void CCWebServlet::SetThreadNumber(int headcount) {
this->numThreads = headcount;
}
void CCWebServlet::Close() {
m_Thread.Stop();
m_ThreadPool.Stop();
m_Socket.Close();
FlagRun = false;
}
bool CCWebServlet::Sign() const {
return FlagRun;
}
void CCWebServlet::SetWebServlet(std::string RootPath, CCWebServlet::RequestFunc RFunc) {
RequestFun.insert(std::pair<std::string, RequestFunc>(RootPath, RFunc));
}
void CCWebServlet::SetAddRootPath(const CCString &rootPath) {
PathSix.push_back(rootPath);
}
void CCWebServlet::SetCorsConfig(CORS &cors) {
CORSConfig = cors;
}

52
SDK/CMakeLists.txt Normal file
View File

@ -0,0 +1,52 @@
cmake_minimum_required(VERSION 3.0)
add_subdirectory(Depend/portaudio)
add_subdirectory(Depend/CSerialPort)
add_subdirectory(Depend/mirrors_nlohmann_json)
option(UIAPIS "APIS" ON)
if (UIAPIS)
add_library(CC_API
STATIC
src/CCThread.cpp
src/CCSocket.cpp
CCServlet/src/CCString.cpp
src/CCSerialPort.cpp
CCServlet/src/CCWeb.cpp
src/CCAudio.cpp
src/CCThreadPool.cpp
include/CCThreadPool.h
src/CCJSONObject.cpp
include/CCJSONObject.h
src/CCFile.cpp
CCServlet/src/CCWebServlet.cpp
CCServlet/include/CCWebServlet.h
CCServlet/src/CCResponse.cpp
CCServlet/include/CCResponse.h
CCServlet/src/CCRequest.cpp
CCServlet/include/CCRequest.h
CCServlet/include/CORS.h
CCServlet/src/CCSQLite3.cpp
CCServlet/include/CCSQLite3.h
src/CCEpoll.cpp
include/CCEpoll.h
)
target_include_directories(CC_API PUBLIC Depend/CSerialPort/include Depend/mirrors_nlohmann_json/include
Depend/portaudio/include Multimedia CCServlet/SQL CCServlet/include CCServlet/SQL include)
if(CMAKE_HOST_UNIX)
target_link_libraries(CC_API PRIVATE libcserialport sqlite3 nlohmann_json PortAudio
${CMAKE_CURRENT_SOURCE_DIR}/Depend/Lib/libs/x86_64/libbass.so
)
elseif(CMAKE_HOST_WIN32)
target_link_libraries(CC_API PRIVATE ws2_32 libcserialport
nlohmann_json
${CMAKE_CURRENT_SOURCE_DIR}/Depend/Bin/bin/sqlite3.dll PortAudio
${CMAKE_CURRENT_SOURCE_DIR}/Depend/Lib/libs/x86_64/bass.lib
)
else()
endif()
endif(UIAPIS)

Binary file not shown.

View File

@ -0,0 +1,361 @@
EXPORTS
sqlite3_aggregate_context
sqlite3_aggregate_count
sqlite3_auto_extension
sqlite3_autovacuum_pages
sqlite3_backup_finish
sqlite3_backup_init
sqlite3_backup_pagecount
sqlite3_backup_remaining
sqlite3_backup_step
sqlite3_bind_blob
sqlite3_bind_blob64
sqlite3_bind_double
sqlite3_bind_int
sqlite3_bind_int64
sqlite3_bind_null
sqlite3_bind_parameter_count
sqlite3_bind_parameter_index
sqlite3_bind_parameter_name
sqlite3_bind_pointer
sqlite3_bind_text
sqlite3_bind_text16
sqlite3_bind_text64
sqlite3_bind_value
sqlite3_bind_zeroblob
sqlite3_bind_zeroblob64
sqlite3_blob_bytes
sqlite3_blob_close
sqlite3_blob_open
sqlite3_blob_read
sqlite3_blob_reopen
sqlite3_blob_write
sqlite3_busy_handler
sqlite3_busy_timeout
sqlite3_cancel_auto_extension
sqlite3_changes
sqlite3_changes64
sqlite3_clear_bindings
sqlite3_close
sqlite3_close_v2
sqlite3_collation_needed
sqlite3_collation_needed16
sqlite3_column_blob
sqlite3_column_bytes
sqlite3_column_bytes16
sqlite3_column_count
sqlite3_column_database_name
sqlite3_column_database_name16
sqlite3_column_decltype
sqlite3_column_decltype16
sqlite3_column_double
sqlite3_column_int
sqlite3_column_int64
sqlite3_column_name
sqlite3_column_name16
sqlite3_column_origin_name
sqlite3_column_origin_name16
sqlite3_column_table_name
sqlite3_column_table_name16
sqlite3_column_text
sqlite3_column_text16
sqlite3_column_type
sqlite3_column_value
sqlite3_commit_hook
sqlite3_compileoption_get
sqlite3_compileoption_used
sqlite3_complete
sqlite3_complete16
sqlite3_config
sqlite3_context_db_handle
sqlite3_create_collation
sqlite3_create_collation_v2
sqlite3_create_collation16
sqlite3_create_filename
sqlite3_create_function
sqlite3_create_function_v2
sqlite3_create_function16
sqlite3_create_module
sqlite3_create_module_v2
sqlite3_create_window_function
sqlite3_data_count
sqlite3_data_directory
sqlite3_database_file_object
sqlite3_db_cacheflush
sqlite3_db_config
sqlite3_db_filename
sqlite3_db_handle
sqlite3_db_mutex
sqlite3_db_name
sqlite3_db_readonly
sqlite3_db_release_memory
sqlite3_db_status
sqlite3_declare_vtab
sqlite3_deserialize
sqlite3_drop_modules
sqlite3_enable_load_extension
sqlite3_enable_shared_cache
sqlite3_errcode
sqlite3_errmsg
sqlite3_errmsg16
sqlite3_error_offset
sqlite3_errstr
sqlite3_exec
sqlite3_expanded_sql
sqlite3_expired
sqlite3_extended_errcode
sqlite3_extended_result_codes
sqlite3_file_control
sqlite3_filename_database
sqlite3_filename_journal
sqlite3_filename_wal
sqlite3_finalize
sqlite3_free
sqlite3_free_filename
sqlite3_free_table
sqlite3_get_autocommit
sqlite3_get_auxdata
sqlite3_get_clientdata
sqlite3_get_table
sqlite3_global_recover
sqlite3_hard_heap_limit64
sqlite3_initialize
sqlite3_interrupt
sqlite3_is_interrupted
sqlite3_keyword_check
sqlite3_keyword_count
sqlite3_keyword_name
sqlite3_last_insert_rowid
sqlite3_libversion
sqlite3_libversion_number
sqlite3_limit
sqlite3_load_extension
sqlite3_log
sqlite3_malloc
sqlite3_malloc64
sqlite3_memory_alarm
sqlite3_memory_highwater
sqlite3_memory_used
sqlite3_mprintf
sqlite3_msize
sqlite3_mutex_alloc
sqlite3_mutex_enter
sqlite3_mutex_free
sqlite3_mutex_leave
sqlite3_mutex_try
sqlite3_next_stmt
sqlite3_open
sqlite3_open_v2
sqlite3_open16
sqlite3_os_end
sqlite3_os_init
sqlite3_overload_function
sqlite3_prepare
sqlite3_prepare_v2
sqlite3_prepare_v3
sqlite3_prepare16
sqlite3_prepare16_v2
sqlite3_prepare16_v3
sqlite3_preupdate_blobwrite
sqlite3_preupdate_count
sqlite3_preupdate_depth
sqlite3_preupdate_hook
sqlite3_preupdate_new
sqlite3_preupdate_old
sqlite3_profile
sqlite3_progress_handler
sqlite3_randomness
sqlite3_realloc
sqlite3_realloc64
sqlite3_release_memory
sqlite3_reset
sqlite3_reset_auto_extension
sqlite3_result_blob
sqlite3_result_blob64
sqlite3_result_double
sqlite3_result_error
sqlite3_result_error_code
sqlite3_result_error_nomem
sqlite3_result_error_toobig
sqlite3_result_error16
sqlite3_result_int
sqlite3_result_int64
sqlite3_result_null
sqlite3_result_pointer
sqlite3_result_subtype
sqlite3_result_text
sqlite3_result_text16
sqlite3_result_text16be
sqlite3_result_text16le
sqlite3_result_text64
sqlite3_result_value
sqlite3_result_zeroblob
sqlite3_result_zeroblob64
sqlite3_rollback_hook
sqlite3_rtree_geometry_callback
sqlite3_rtree_query_callback
sqlite3_serialize
sqlite3_set_authorizer
sqlite3_set_auxdata
sqlite3_set_clientdata
sqlite3_set_last_insert_rowid
sqlite3_shutdown
sqlite3_sleep
sqlite3_snprintf
sqlite3_soft_heap_limit
sqlite3_soft_heap_limit64
sqlite3_sourceid
sqlite3_sql
sqlite3_status
sqlite3_status64
sqlite3_step
sqlite3_stmt_busy
sqlite3_stmt_explain
sqlite3_stmt_isexplain
sqlite3_stmt_readonly
sqlite3_stmt_status
sqlite3_str_append
sqlite3_str_appendall
sqlite3_str_appendchar
sqlite3_str_appendf
sqlite3_str_errcode
sqlite3_str_finish
sqlite3_str_length
sqlite3_str_new
sqlite3_str_reset
sqlite3_str_value
sqlite3_str_vappendf
sqlite3_strglob
sqlite3_stricmp
sqlite3_strlike
sqlite3_strnicmp
sqlite3_system_errno
sqlite3_table_column_metadata
sqlite3_temp_directory
sqlite3_test_control
sqlite3_thread_cleanup
sqlite3_threadsafe
sqlite3_total_changes
sqlite3_total_changes64
sqlite3_trace
sqlite3_trace_v2
sqlite3_transfer_bindings
sqlite3_txn_state
sqlite3_update_hook
sqlite3_uri_boolean
sqlite3_uri_int64
sqlite3_uri_key
sqlite3_uri_parameter
sqlite3_user_data
sqlite3_value_blob
sqlite3_value_bytes
sqlite3_value_bytes16
sqlite3_value_double
sqlite3_value_dup
sqlite3_value_encoding
sqlite3_value_free
sqlite3_value_frombind
sqlite3_value_int
sqlite3_value_int64
sqlite3_value_nochange
sqlite3_value_numeric_type
sqlite3_value_pointer
sqlite3_value_subtype
sqlite3_value_text
sqlite3_value_text16
sqlite3_value_text16be
sqlite3_value_text16le
sqlite3_value_type
sqlite3_version
sqlite3_vfs_find
sqlite3_vfs_register
sqlite3_vfs_unregister
sqlite3_vmprintf
sqlite3_vsnprintf
sqlite3_vtab_collation
sqlite3_vtab_config
sqlite3_vtab_distinct
sqlite3_vtab_in
sqlite3_vtab_in_first
sqlite3_vtab_in_next
sqlite3_vtab_nochange
sqlite3_vtab_on_conflict
sqlite3_vtab_rhs_value
sqlite3_wal_autocheckpoint
sqlite3_wal_checkpoint
sqlite3_wal_checkpoint_v2
sqlite3_wal_hook
sqlite3_win32_is_nt
sqlite3_win32_mbcs_to_utf8
sqlite3_win32_mbcs_to_utf8_v2
sqlite3_win32_set_directory
sqlite3_win32_set_directory16
sqlite3_win32_set_directory8
sqlite3_win32_sleep
sqlite3_win32_unicode_to_utf8
sqlite3_win32_utf8_to_mbcs
sqlite3_win32_utf8_to_mbcs_v2
sqlite3_win32_utf8_to_unicode
sqlite3_win32_write_debug
sqlite3changegroup_add
sqlite3changegroup_add_strm
sqlite3changegroup_delete
sqlite3changegroup_new
sqlite3changegroup_output
sqlite3changegroup_output_strm
sqlite3changegroup_schema
sqlite3changeset_apply
sqlite3changeset_apply_strm
sqlite3changeset_apply_v2
sqlite3changeset_apply_v2_strm
sqlite3changeset_concat
sqlite3changeset_concat_strm
sqlite3changeset_conflict
sqlite3changeset_finalize
sqlite3changeset_fk_conflicts
sqlite3changeset_invert
sqlite3changeset_invert_strm
sqlite3changeset_new
sqlite3changeset_next
sqlite3changeset_old
sqlite3changeset_op
sqlite3changeset_pk
sqlite3changeset_start
sqlite3changeset_start_strm
sqlite3changeset_start_v2
sqlite3changeset_start_v2_strm
sqlite3rbu_bp_progress
sqlite3rbu_close
sqlite3rbu_create_vfs
sqlite3rbu_db
sqlite3rbu_destroy_vfs
sqlite3rbu_open
sqlite3rbu_progress
sqlite3rbu_rename_handler
sqlite3rbu_savestate
sqlite3rbu_state
sqlite3rbu_step
sqlite3rbu_temp_size
sqlite3rbu_temp_size_limit
sqlite3rbu_vacuum
sqlite3rebaser_configure
sqlite3rebaser_create
sqlite3rebaser_delete
sqlite3rebaser_rebase
sqlite3rebaser_rebase_strm
sqlite3session_attach
sqlite3session_changeset
sqlite3session_changeset_size
sqlite3session_changeset_strm
sqlite3session_config
sqlite3session_create
sqlite3session_delete
sqlite3session_diff
sqlite3session_enable
sqlite3session_indirect
sqlite3session_isempty
sqlite3session_memory_used
sqlite3session_object_config
sqlite3session_patchset
sqlite3session_patchset_strm
sqlite3session_table_filter

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,164 @@
# Run manually to reformat file
# clang-format -i --style=file <file>
# http://clang.llvm.org/docs/ClangFormatStyleOptions.html
# 语言: None, Cpp, Java, JavaScript, ObjC, Proto, TableGen, TextProto
Language: Cpp
# BasedOnStyle: LLVM
# 访问说明符(public、private等)的偏移
AccessModifierOffset: -4
# 开括号(开圆括号、开尖括号、开方括号)后的对齐
AlignAfterOpenBracket: Align
# 连续赋值时,等号对齐
AlignConsecutiveAssignments: false
# 连续赋值时,变量名对齐
AlignConsecutiveDeclarations: false
# 左对齐逃脱换行(使用反斜杠换行)的反斜杠
AlignEscapedNewlinesLeft: true
# 水平对齐二元和三元表达式的操作数
AlignOperands: true
# 对齐连续的尾随的注释
AlignTrailingComments: true
# 允许函数声明的所有参数在放在下一行
AllowAllParametersOfDeclarationOnNextLine: false
# 允许短的块放在同一行
AllowShortBlocksOnASingleLine: false
# 允许短的case标签放在同一行
AllowShortCaseLabelsOnASingleLine: false
# 允许短的函数放在同一行: None, InlineOnly(定义在类中), Empty(空函数), Inline(定义在类中,空函数), All
AllowShortFunctionsOnASingleLine: Empty
# 允许短的if语句保持在同一行
AllowShortIfStatementsOnASingleLine: false
# 允许短的循环保持在同一行
AllowShortLoopsOnASingleLine: false
# 总是在定义返回类型后换行(deprecated)
AlwaysBreakAfterDefinitionReturnType: None
# 总是在返回类型后换行: None, All, TopLevel(顶级函数,不包括在类中的函数),
# AllDefinitions(所有的定义,不包括声明), TopLevelDefinitions(所有的顶级函数的定义)
AlwaysBreakAfterReturnType: None
# 总是在多行string字面量前换行
AlwaysBreakBeforeMultilineStrings: true
# 总是在template声明后换行
AlwaysBreakTemplateDeclarations: false
# false表示函数实参要么都在同一行要么都各自一行
BinPackArguments: true
# false表示所有形参要么都在同一行要么都各自一行
BinPackParameters: false
# 大括号换行只有当BreakBeforeBraces设置为Custom时才有效
BraceWrapping:
AfterClass: false
AfterControlStatement: false
AfterEnum: false
AfterFunction: true
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
BeforeCatch: false
BeforeElse: false
IndentBraces: false
# 在二元运算符前换行: None(在操作符后换行), NonAssignment(在非赋值的操作符前换行), All(在操作符前换行)
BreakBeforeBinaryOperators: None
# 在大括号前换行: Attach(始终将大括号附加到周围的上下文), Linux(除函数、命名空间和类定义与Attach类似),
# Mozilla(除枚举、函数、记录定义与Attach类似), Stroustrup(除函数定义、catch、else与Attach类似),
# Allman(总是在大括号前换行), GNU(总是在大括号前换行,并对于控制语句的大括号增加额外的缩进), WebKit(在函数前换行), Custom
# 注:这里认为语句块也属于函数
BreakBeforeBraces: Allman
# 在三元运算符前换行
BreakBeforeTernaryOperators: true
# 每行字符的限制0表示没有限制
ColumnLimit: 180
# 描述具有特殊意义的注释的正则表达式,它不应该被分割为多行或以其它方式改变
CommentPragmas: "^ IWYU pragma:"
# 在构造函数的初始化列表的逗号前换行
BreakConstructorInitializersBeforeComma: true
# 构造函数的初始化列表要么都在同一行,要么都各自一行
ConstructorInitializerAllOnOneLineOrOnePerLine: false
# 构造函数的初始化列表的缩进宽度
ConstructorInitializerIndentWidth: 4
# 延续的行的缩进宽度
ContinuationIndentWidth: 4
# 去除C++11的列表初始化的大括号{后和}前的空格
Cpp11BracedListStyle: true
# 继承最常用的指针和引用的对齐方式
DerivePointerAlignment: false
# 关闭格式化
DisableFormat: false
# 自动检测函数的调用和定义是否被格式为每行一个参数(Experimental)
ExperimentalAutoDetectBinPacking: false
# 需要被解读为foreach循环而不是函数调用的宏
ForEachMacros: [foreach, Q_FOREACH, BOOST_FOREACH]
# 对#include进行排序匹配了某正则表达式的#include拥有对应的优先级匹配不到的则默认优先级为INT_MAX(优先级越小排序越靠前)
# 可以定义负数优先级从而保证某些#include永远在最前面
IncludeCategories:
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
Priority: 2
- Regex: '^(<|"(gtest|isl|json)/)'
Priority: 3
- Regex: ".*"
Priority: 1
# 缩进case标签
IndentCaseLabels: true
# 缩进宽度
IndentWidth: 4
# 函数返回类型换行时,缩进函数声明或函数定义的函数名
IndentWrappedFunctionNames: true
# 保留在块开始处的空行
KeepEmptyLinesAtTheStartOfBlocks: true
# 开始一个块的宏的正则表达式
MacroBlockBegin: ""
# 结束一个块的宏的正则表达式
MacroBlockEnd: ""
# 连续空行的最大数量
MaxEmptyLinesToKeep: 1
# 命名空间的缩进: None, Inner(缩进嵌套的命名空间中的内容), All
NamespaceIndentation: None
# 使用ObjC块时缩进宽度
ObjCBlockIndentWidth: 4
# 在ObjC的@property后添加一个空格
ObjCSpaceAfterProperty: false
# 在ObjC的protocol列表前添加一个空格
ObjCSpaceBeforeProtocolList: true
# 在call(后对函数调用换行的penalty
PenaltyBreakBeforeFirstCallParameter: 19
# 在一个注释中引入换行的penalty
PenaltyBreakComment: 300
# 第一次在<<前换行的penalty
PenaltyBreakFirstLessLess: 120
# 在一个字符串字面量中引入换行的penalty
PenaltyBreakString: 1000
# 对于每个在行字符数限制之外的字符的penalt
PenaltyExcessCharacter: 1000000
# 将函数的返回类型放到它自己的行的penalty
PenaltyReturnTypeOnItsOwnLine: 60
# 指针和引用的对齐: Left, Right, Middle
PointerAlignment: Right
# 允许重新排版注释
ReflowComments: true
# 允许排序#include
SortIncludes: false
# 在C风格类型转换后添加空格
SpaceAfterCStyleCast: false
# 在赋值运算符之前添加空格
SpaceBeforeAssignmentOperators: true
# 开圆括号之前添加一个空格: Never, ControlStatements, Always
SpaceBeforeParens: ControlStatements
# 在空的圆括号中添加空格
SpaceInEmptyParentheses: false
# 在尾随的评论前添加的空格数(只适用于//)
SpacesBeforeTrailingComments: 1
# 在尖括号的<后和>前添加空格
SpacesInAngles: false
# 在容器(ObjC和JavaScript的数组和字典等)字面量中添加空格
SpacesInContainerLiterals: true
# 在C风格类型转换的括号中添加空格
SpacesInCStyleCastParentheses: false
# 在圆括号的(后和)前添加空格
SpacesInParentheses: false
# 在方括号的[后和]前添加空格lamda表达式和未指明大小的数组的声明不受影响
SpacesInSquareBrackets: false
# 标准: Cpp03, Cpp11, Auto
Standard: Cpp11
# tab宽度
TabWidth: 4
# 使用tab字符: Never, ForIndentation, ForContinuationAndIndentation, Always
UseTab: Never

View File

@ -0,0 +1 @@
Checks: 'clang-diagnostic-*,clang-analyzer-*'

63
SDK/Depend/CSerialPort/.gitattributes vendored Normal file
View File

@ -0,0 +1,63 @@
###############################################################################
# Set default behavior to automatically normalize line endings.
###############################################################################
* text=auto
###############################################################################
# Set default behavior for command prompt diff.
#
# This is need for earlier builds of msysgit that does not have it on by
# default for csharp files.
# Note: This is only used by command line
###############################################################################
#*.cs diff=csharp
###############################################################################
# Set the merge driver for project and solution files
#
# Merging from the command prompt will add diff markers to the files if there
# are conflicts (Merging from VS is not affected by the settings below, in VS
# the diff markers are never inserted). Diff markers may cause the following
# file extensions to fail to load in VS. An alternative would be to treat
# these files as binary and thus will always conflict and require user
# intervention with every merge. To do so, just uncomment the entries below
###############################################################################
#*.sln merge=binary
#*.csproj merge=binary
#*.vbproj merge=binary
#*.vcxproj merge=binary
#*.vcproj merge=binary
#*.dbproj merge=binary
#*.fsproj merge=binary
#*.lsproj merge=binary
#*.wixproj merge=binary
#*.modelproj merge=binary
#*.sqlproj merge=binary
#*.wwaproj merge=binary
###############################################################################
# behavior for image files
#
# image files are treated as binary by default.
###############################################################################
#*.jpg binary
#*.png binary
#*.gif binary
###############################################################################
# diff behavior for common document formats
#
# Convert binary document formats to text before diffing them. This feature
# is only available from the command line. Turn it on by uncommenting the
# entries below.
###############################################################################
#*.doc diff=astextplain
#*.DOC diff=astextplain
#*.docx diff=astextplain
#*.DOCX diff=astextplain
#*.dot diff=astextplain
#*.DOT diff=astextplain
#*.pdf diff=astextplain
#*.PDF diff=astextplain
#*.rtf diff=astextplain
#*.RTF diff=astextplain

68
SDK/Depend/CSerialPort/.gitignore vendored Normal file
View File

@ -0,0 +1,68 @@
/Demo/CSerialPortDemoWin32Console/CSerialPortDemoWin32Console/Debug
/Demo/CSerialPortDemoWin32/ipch
/Demo/CSerialPortDemoWin32/CSerialPortDemoWin32/Debug
/Demo/CSerialPortDemoWin32/Debug/CSerialPortDemoWin32.ilk
/Demo/CSerialPortDemoWin32/Debug/CSerialPortDemoWin32.pdb
/Demo/CSerialPortDemoWin32/*.sdf
/Demo/CSerialPortDemoWin32/CSerialPortDemoWin32.sdf
/Demo/Comm/Comm/Debug
/Demo/Comm/ipch
/Demo/Comm/*.sdf
/Demo/Comm/Debug/*.ilk
/Demo/Comm/Debug/*.pdb
/Demo/Comm/Debug
/projects/Windows/VC12/libCSerialPort/Debug
/projects/Windows/VC12/libCSerialPort/ipch
/projects/Windows/VC12/libCSerialPort/libCSerialPort.opensdf
/projects/Windows/VC12/libCSerialPort/libCSerialPort.sdf
/projects/Windows/VC12/libCSerialPort/libCSerialPort.v12.suo
/vsprojects/Windows/VC12/libcserialport/*.sdf
/vsprojects/Windows/VC12/libcserialport/Release
/vsprojects/Windows/VC12/libcserialport/Debug
/vsprojects/Windows/VC12/libcserialport/ipch
/vsprojects/Windows/VC12/libcserialport/*.suo
/vsprojects/Windows/VC12/libcserialport/libcserialport/Debug
/vsprojects/Windows/VC12/libcserialport/libcserialport/Release
/Demo/Comm/Comm/Release
/Demo/Comm/Release/Comm.exp
/Demo/Comm/Release/Comm.lib
/Demo/Comm/Release/Comm.pdb
/Demo/Comm/Comm.opensdf
/Demo/Comm/Comm.v12.suo
/Demo/CommDLL/Debug
/Demo/CommDLL/ipch
/Demo/CommDLL/Comm.opensdf
/Demo/CommDLL/Comm.sdf
/Demo/CommDLL/Comm.v12.suo
/Demo/CommDLL/Comm/libcserialport.lib
/Demo/CommDLL/Comm/CLog4CPP.cpp
/Demo/CommDLL/Comm/CLog4CPP.h
/Demo/CommDLL/Comm/Debug
/Demo/CommDLL/Comm/Release
/Demo/CommDLL/Release/*.dll
/Demo/CommDLL/Release/Comm.exp
/Demo/CommDLL/Release/Comm.lib
/Demo/CommDLL/Release/Comm.pdb
/vsprojects/Windows/VC12/libcserialport/libcserialport.opensdf
/Demo/CSerialPortDemoWin32/Debug/CSerialPortDemoWin32.exp
/Demo/CSerialPortDemoWin32/Debug/CSerialPortDemoWin32.lib
/Demo/CSerialPortDemoWin32/Debug
/Demo/CSerialPortDemoWin32/CSerialPortDemoWin32.v12.suo
/Demo/CSerialPortDemoWin32Console/*.opensdf
/Demo/CSerialPortDemoWin32Console/*.sdf
/Demo/CSerialPortDemoWin32Console/*.suo
/Demo/CSerialPortDemoWin32Console/Debug/CSerialPortDemoWin32Console.exe
/Demo/CSerialPortDemoWin32Console/Debug/*.exp
/Demo/CSerialPortDemoWin32Console/Debug/*.ilk
/Demo/CSerialPortDemoWin32Console/Debug/*.lib
/Demo/CSerialPortDemoWin32Console/Debug/*.pdb
/Demo/CSerialPortDemoWin32Console/ipch/cserialportdemowin32console-48694deb/*.ipch
/Demo/CSerialPortDemoWin32Console/Debug
/Demo/CSerialPortDemoWin32Console/ipch
/lib/Windows/VC12/libcserialport/*.sdf
/lib/Windows/VC12/libcserialport/*
/lib/Windows/VC12/libcserialport/*.opensdf
/lib/Windows/VC12/libcserialport/libcserialport/*.txt
/lib/Windows/VC12/libcserialport/libcserialport/*
/lib/Windows/VC12/libcserialport/libcserialport/*.user
/Demo/Comm/*.suo

3
SDK/Depend/CSerialPort/.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "test/googletest"]
path = test/googletest
url = https://gitee.com/itas109/googletest.git

View File

@ -0,0 +1,164 @@
#***************************************************************************
# @file .travis.yml
# @author itas109 (itas109@qq.com) \n\n
# Blog : https://blog.csdn.net/itas109 \n
# Github : https://github.com/itas109 \n
# Gitee : https://gitee.com/itas109 \n
# QQ Group : 129518033
# @brief Lightweight cross-platform serial port library based on C++
# @copyright The CSerialPort is Copyright (C) 2014 itas109 <itas109@qq.com>.
# You may use, copy, modify, and distribute the CSerialPort, under the terms
# of the LICENSE file.
############################################################################
language: cpp
# https://docs.travis-ci.com/user/languages/cpp
# default
os: linux
dist: xenial
git:
depth: 1
submodules: false
jobs:
include:
# Test gcc-4.8: Build=Debug/Release
- env: GCC_VERSION=4.8 BUILD_TYPE=Debug BUILD_TEST=OFF
os: linux
arch: amd64
dist: trusty
addons:
apt:
packages:
- g++-4.8
sources:
- ubuntu-toolchain-r-test
# - env: GCC_VERSION=4.8 BUILD_TYPE=Release BUILD_TEST=OFF
# os: linux
# arch: arm64
# dist: trusty
# addons:
# apt:
# packages:
# - g++-4.8
# sources:
# - ubuntu-toolchain-r-test
# Test gcc-5.4.0: Build=Debug/Release
# - env: GCC_VERSION=5 BUILD_TYPE=Debug BUILD_TEST=OFF
# os: linux
# arch: s390x
# dist: xenial
# # addons:
# # apt:
# # packages:
# # - g++-7
# # sources:
# # - ubuntu-toolchain-r-test
# - env: GCC_VERSION=7 BUILD_TYPE=Release BUILD_TEST=OFF
# os: linux
# arch: ppc64le
# dist: xenial
# addons:
# apt:
# packages:
# - g++-7
# sources:
# - ubuntu-toolchain-r-test
# Test clang-3.5: Build=Debug/Release
- env: CLANG_VERSION=3.5 BUILD_TYPE=Debug BUILD_TEST=OFF
os: linux
arch: amd64
dist: xenial
addons:
apt:
packages:
- clang-3.5
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.5
- env: CLANG_VERSION=3.5 BUILD_TYPE=Release BUILD_TEST=OFF
os: linux
arch: amd64
dist: xenial
addons:
apt:
packages:
- clang-3.5
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.5
# Test clang-10.0: Build=Debug/Release
- env: CLANG_VERSION=10 BUILD_TYPE=Debug BUILD_TEST=OFF
os: linux
arch: arm64
dist: bionic
addons:
apt:
packages:
- clang-10
sources:
- sourceline: "deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-10 main"
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
- env: CLANG_VERSION=10 BUILD_TYPE=Release BUILD_TEST=OFF
os: linux
arch: amd64
dist: bionic
addons:
apt:
packages:
- clang-10
sources:
- sourceline: "deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-10 main"
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
# ubuntu 20.04 gcc 9.3.0
- env: BUILD_TYPE=Release BUILD_TEST=OFF
os: linux
dist: focal
# ubuntu 22.04 gcc 11.2.0
- env: BUILD_TYPE=Release BUILD_TEST=ON
os: linux
dist: jammy
# osx default macOS 10.13
- env: BUILD_TYPE=Release BUILD_TEST=OFF
os: osx
# freebsd default FreeBSD 12.1
- env: BUILD_TYPE=Release BUILD_TEST=OFF
os: freebsd
before_script:
- if [ -n "$GCC_VERSION" ]; then export CXX="g++-${GCC_VERSION}" CC="gcc-${GCC_VERSION}"; fi
- if [ -n "$CLANG_VERSION" ]; then export CXX="clang++-${CLANG_VERSION}" CC="clang-${CLANG_VERSION}"; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then export CXX="clang++" CC="clang"; fi
- if [[ "$TRAVIS_OS_NAME" == "freebsd" ]]; then export CXX="clang++" CC="clang"; fi
- which $CXX
- which $CC
- $CXX --version
- cmake --version
script:
- cd ${TRAVIS_BUILD_DIR}
- mkdir bin
- cd bin
- |
cmake .. \
-DCMAKE_INSTALL_PREFIX=install \
-DCMAKE_BUILD_TYPE=$BUILD_TYPE \
-DCSERIALPORT_BUILD_TEST=$BUILD_TEST
- cmake --build .
- cmake --install .
- if [ "$BUILD_TEST" = "ON" ]; then ./bin/CSerialPortTest; fi

View File

@ -0,0 +1,133 @@
# CSerialPort Changelog
## v4.3.1 (2024-02-04)
Feature:
* support linux and macos get hardwareId info 支持linux和macos获取硬件信息vid和pid
* support DTR RTS set 支持DTR和RTS设置
* support flush RX TX buffers 支持刷新读写缓冲区
* support add CSeiralPort as subdirectory 支持CSeiralPort 作为cmake子目录
* use c++11 timer if compiler support 编译器支持的情况下使用C++定时器
Fixed:
* #75 fix getPortInfoList crash on macos 修复macos下getPortInfoList 崩溃问题
* #76 linux custom baudrate not work 修复linux下自定义波特率无效问题
* #80 unix read undefinite wait when sync mode 修复unix同步模式下读取无限等待问题
---
## v4.3.0 (2023-02-15)
Feature:
* readEvent replace with CSerialPortListener 使用CSerialPortListener进行读取事件通知
* replace std::string with const char* as much as possible 尽可能使用const char*代替std::string
* add function getReadBufferUsedLen() to get used buffer length 增加getReadBufferUsedLen函数用于获取缓冲区长度
* add LOG_INFO to output CSerialPort info 增加LOG_INFO输出串口信息
## v4.2.2 (2023-02-15)
Feature:
* read event notify with portName and readBufferLen 读取事件通知支持串口名称与长度
* add function getReadBufferUsedLen() to get used buffer length 增加getReadBufferUsedLen函数用于获取缓冲区长度
* add LOG_INFO to output CSerialPort info 增加LOG_INFO输出串口信息
## v4.2.1 (2022-11-07)
Feature:
* read buffer size deafult 4096 Bytes 读取缓冲区大小默认为4096字节
* read interval timeout default 0ms 读取超时间隔默认0ms即实时接收
* vcpkg install CSerialPort 支持vcpkg安装CSerialPort
* wxWidgets demo 新增wxWidgets示例程序
Experimental:
* new notify class CSerialPortListener(USE_CSERIALPORT_LISTENER) 新的事件通知类CSerialPortListener(宏定义USE_CSERIALPORT_LISTENER开启)
* CSerialPort for C#(CSharp) 支持C#(CSharp)调用CSerialPort
* CSerialPort for Java 支持Java调用CSerialPort
* CSerialPort for Python 支持Python调用CSerialPort
* CSerialPort for JavaScript 支持JavaScript调用CSerialPort
## v4.2.0 (2022-10-01)
Fixed:
* #60 application compiled with source code under windows still has export information 在windows下以源码方式编译仍然带有导出信息
Feature:
* modify examples 优化示例程序
* add cross compile toochain.cmake for arm aarch64 mips64el riscv 增加arm aarch64 mips64el riscv的交叉编译cmake 文件
* improve windows receive performance 优化windows接收性能
* add custom baud rate for linux 新增linux下设置自定义波特率
* add cross-platform thread library 新增跨平台线程库
* add cross-platform ringbuffer library 新增跨平台环形缓冲区库
* add cross-platform timer based condition variable 新增基于条件变量的跨平台定时器库
* add ringbuffer for receive data(asynchronous mode) 新增环形缓冲区接收数据(异步模式)
* add read interval timeout setting(default 50ms, asynchronous mode) 新增读取超时设置(默认50ms, 异步模式)
* add clang-tidy 增加clang-tidy代码检测
## v4.1.1 (2021-09-03)
Fixed:
* #49 function writeData hanle leak on windows 修复windows下writeData函数句柄泄漏问题
* #41 could not enum all avaiable ports on windows 修复windows下偶尔枚举可用串口不全的问题
* #42 high cpu usage problem on unix 修复unix上高cpu占用问题
* #33 No Gui Application without endless loop crash problem 修复NoGui程序崩溃问题
* #28 VS2015 x64 MFC not work 修复VS2015生成x64程序不能正常运行问题
Feature:
* use unsigned int instead of int64 使用unsigned int代替int64
* add unix virtual serial port 增加unix虚拟串口工具
* read thread optimization 读取线程优化
## 4.1.0 (2020-10-10)
Fixed:
* #29 windows xp unable to locate the program input point in msvcrt.dll 无法定位程序输入点于msvcrt.dll
* #30 _T() cannot convert 'const char*' to 'LPCWSTR
* #39 fix getPortInfoList crash on unix(not linux and mac os) 修复unix系统(非linux和macos)getPortInfoList引起的崩溃问题
* #40 fix vs2008 vs2010 Cannot open include file: 'ntddser.h' 修复msvc无法找到ntddser.h问题
Feature:
* header files is separated into include directory 头文件独立到include文件夹
* add Tui Demo based pdcurses and ncurses 增加基于pdcurses和ncurses的tui示例
* use cmake compile CSerialPort 使用cmake编译
* add cmake install 增加cmake安装
* add cppcheck file 增加cppcheck代码检测文件
* add clang-format 增加clang-format代码格式化
* add travis ci and appveyor ci 增加travis和appveyor持续集成
Remove:
* remove function init of integer port 移除init整型串口函数
* remove function availablePorts and availableFriendlyPorts 移除availablePorts和availablePorts函数
## 4.0.3 (2020-04-29)
Fixed:
* fixed memory leak 修复内存泄露问题
* Optimize function closePort under windows 优化windows下的closePort函数
* #21 typo setFlowControl
* #22 function CSerialPortWinBase::openPort error when set error parameter
* #24 sigslot can not define static
* #26 linux receive miss 0x11 0x13 0x0d
* fixed compile error when baudrate not difine 修复波特率未定义错误
Feature:
* support mingw 支持mingw 4.8.2
* support mac 支持mac 10.13
* add Common baud rate 增加波特率
* add test case by gtest 增加测试用例
* add function CSerialPortInfo::availablePortInfos 增加通用串口信息枚举函数
* support linux list ports add /dev/pts/* 支持linux虚拟串口
---
## 4.0.2 (2020-01-08)
基础稳定版本
base and stable version
---
## 4.0.1 beta (2019-07-30)
测试第一版
first beta version

View File

@ -0,0 +1,70 @@
#***************************************************************************
# @file CMakeLists.txt
# @author itas109 (itas109@qq.com) \n\n
# Blog : https://blog.csdn.net/itas109 \n
# Github : https://github.com/itas109 \n
# Gitee : https://gitee.com/itas109 \n
# QQ Group : 129518033
# @brief Lightweight cross-platform serial port library based on C++
# @copyright The CSerialPort is Copyright (C) 2014 itas109 <itas109@qq.com>.
# You may use, copy, modify, and distribute the CSerialPort, under the terms
# of the LICENSE file.
############################################################################
cmake_minimum_required(VERSION 2.8.12)
project(CSerialPort LANGUAGES CXX)
# set output directory
if (CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
endif()
# set build tpye
if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Debug CACHE STRING "Choose the type of build." FORCE)
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo")
endif()
option(BUILD_SHARED_LIBS "Build shared libraries" ON)
option(CSERIALPORT_BUILD_EXAMPLES "Build CSerialPort examples" ON)
option(CSERIALPORT_BUILD_DOC "Build CSerialPort Doc" OFF)
option(CSERIALPORT_BUILD_TEST "Build CSerialPort Test" OFF)
# only build library if add CSeiralPort as subdirectory
if (NOT CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
set(CSERIALPORT_BUILD_EXAMPLES OFF)
set(CSERIALPORT_BUILD_DOC OFF)
set(CSERIALPORT_BUILD_TEST OFF)
endif()
message(STATUS "CSerialPort CMake Info")
message(STATUS "=======================================================")
message(STATUS " Operation System : ${CMAKE_SYSTEM}")
message(STATUS " CPU Architecture : ${CMAKE_SYSTEM_PROCESSOR}")
message(STATUS " Build Type : ${CMAKE_BUILD_TYPE}")
message(STATUS " Shared Library : ${BUILD_SHARED_LIBS}")
message(STATUS " Build Examples : ${CSERIALPORT_BUILD_EXAMPLES}")
message(STATUS " Build Doc : ${CSERIALPORT_BUILD_DOC}")
message(STATUS " Build Test : ${CSERIALPORT_BUILD_TEST}")
message(STATUS "=======================================================")
# libcserialport
add_subdirectory(lib)
# examples
if (CSERIALPORT_BUILD_EXAMPLES)
add_subdirectory(examples)
endif ()
# test
if (CSERIALPORT_BUILD_TEST)
add_subdirectory(test)
endif ()
# doc
if (CSERIALPORT_BUILD_DOC)
add_subdirectory(doc)
endif ()

View File

@ -0,0 +1,186 @@
Copyright (C) 2014 itas109 <itas109@qq.com>.
All Rights Reserved.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of a copyright holder shall not
be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization of the copyright holder.
You may use, copy, modify, and distribute the CSerialPort under the terms of
GNU Lesser General Public License version 3, which is displayed below.
-------------------------------------------------------------------------
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.

View File

@ -0,0 +1,230 @@
# [CSerialPort](https://github.com/itas109/CSerialPort)
[中文](README_zh_CN.md)
CSerialPort is a lightweight cross-platform serial port library based on C/C++, which can easy to read and write serial port on multiple operating system. Also support C#, Java, Python, Node.js etc.
<p>
<a href="https://github.com/itas109/CSerialPort/releases"><img alt="Version" src="https://img.shields.io/github/release/itas109/CSerialPort"/></a>
<a href="https://github.com/itas109/CSerialPort/stargazers"><img alt="Stars" src="https://img.shields.io/github/stars/itas109/CSerialPort"/></a>
<a href="https://gitee.com/itas109/CSerialPort"><img alt="Stars" src="https://gitee.com/itas109/CSerialPort/badge/star.svg?theme=dark"/></a>
<a href="https://github.com/itas109/CSerialPort/blob/master/LICENSE"><img alt="License" src="https://img.shields.io/badge/License-LGPL%203.0-orange"/></a>
<img alt="language" src="https://img.shields.io/badge/language-c++-red"/>
<img alt="appveyor-ci" src="https://ci.appveyor.com/api/projects/status/a4t6ddubhns561kh?svg=true"/>
<!-- <img alt="travis-ci" src="https://www.travis-ci.org/itas109/CSerialPort.svg?branch=master"/> -->
</p>
---
# Design Principles
- Cross-platform
- Easy to use
- Higher efficiency
# Platform
CSerialPort was tested on the following platforms
- Windows ( x86, x86_64, arm64 )
- Linux ( x86, x86_64, arm, arm64/aarch64, mips64el, riscv, s390x, ppc64le )
- macOS ( x86_64 )
- Raspberry Pi ( armv7l )
- FreeBSD ( x86_64 )
- ...
# Todo List
## Long-term Goal
- [x] 1.support windows and linux first
- [ ] 2.add communicating protocol
- [x] 3.support hot swap - [CSerialPortExtend](https://github.com/itas109/CSerialPortExtend)
- [x] 4.higher efficiency notify module - replace with CSerialPortListener
- [x] 5.support other language - C#, Java, Python, Node.js etc. - more information [bindings](https://github.com/itas109/CSerialPort/tree/master/bindings)
- [x] 6.sync serial port communication
- [x] 7.new cross-platform gui serial port tool - [CommMaster](https://gitee.com/itas109/CommMaster)
- [x] 8.add introduction and tutorial of CSerialPort - [CSerialPort Tutorial ](https://blog.csdn.net/itas109/category_12416341.html)
- [ ] 9.serial port monitor hook
## Short-term Goal
- [x] 1.cross-platform OS identify class
- [x] 2.cross-platform thread class
- [x] 3.cross-platform lock class
- [x] 4.cross-platform higher efficiency timer class
- [ ] 5.cross-platform thread pool class
- [ ] 6.Performance test report(Throughput && delay && packet dropout rates)
# Latest version
## Version: 4.3.1.240204
by itas109 on 2024-02-04
# Quick Start
```
$ git clone --depth=1 https://github.com/itas109/CSerialPort.git
$ cd CSerialPort
$ mkdir bin && cd bin
$ cmake ..
$ cmake --build .
```
run demo ( for example serial port lookback test on linux)
```
CSerialPort/bin $ ./CSerialPortDemoNoGui
Version: https://github.com/itas109/CSerialPort - V4.3.1.240204
AvailableFriendlyPorts:
1 - /dev/ttyUSB0 QinHeng CH340 serial converter 1a86:7523
2 - /dev/pts/0 0 pty terminal
Please Input The Index Of Port(1 - 2)
1
Port Name: /dev/ttyUSB0
[CSERIALPORT_DEBUG] openPort - portName: /dev/ttyUSB0, baudRate: 9600, dataBit: 8, parity: 0, stopBit: 0, flowControl: 0, mode: async, readBufferSize:4096(4096), readIntervalTimeoutMS: 0, minByteReadNotify: 1
[CSERIALPORT_DEBUG] openPort - open /dev/ttyUSB0. code: 0, message: success
Open /dev/ttyUSB0 Success
Code: 0, Message: success
[CSERIALPORT_DEBUG] writeData - write. len: 5, hex(top100): 3132333435
[CSERIALPORT_DEBUG] writeData - write. len: 7, hex(top100): 69746173313039
[CSERIALPORT_DEBUG] commThreadMonitor - write buffer(usedLen 12). len: 12, hex(top100): 313233343569746173313039
[CSERIALPORT_DEBUG] commThreadMonitor - onReadEvent. portName: /dev/ttyUSB0, readLen: 12
[CSERIALPORT_DEBUG] readData - read. len: 12, hex(top100): 313233343569746173313039
/dev/ttyUSB0 - Count: 1, Length: 12, Str: 12345itas109, Hex: 0x31 0x32 0x33 0x34 0x35 0x69 0x74 0x61 0x73 0x31 0x30 0x39
```
# Install CSerialPort Using Vcpkg
You can download and install CSerialPort using the [vcpkg](https://github.com/Microsoft/vcpkg/) dependency manager
```
$ git clone https://github.com/Microsoft/vcpkg.git
$ cd vcpkg
$ ./bootstrap-vcpkg.sh
$ ./vcpkg install cserialport
```
# Cross Compile
- arm on ubuntu 20.04
```
$ sudo apt-get install g++-arm-linux-gnueabi
$ cd CSerialPort
$ mkdir bin_arm && cd bin_arm
$ cmake .. -DCMAKE_TOOLCHAIN_FILE=./cmake/toolchain_arm.cmake
$ cmake --build .
```
- aarch64 on ubuntu 20.04
```
$ sudo apt-get install g++-aarch64-linux-gnu
$ cd CSerialPort
$ mkdir bin_aarch64 && cd bin_aarch64
$ cmake .. -DCMAKE_TOOLCHAIN_FILE=./cmake/toolchain_aarch64.cmake
$ cmake --build .
```
- mips64el on ubuntu 20.04
```
$ sudo apt-get install g++-mips64el-linux-gnuabi64
$ cd CSerialPort
$ mkdir bin_mips64el && cd bin_mips64el
$ cmake .. -DCMAKE_TOOLCHAIN_FILE=./cmake/toolchain_mips64el.cmake
$ cmake --build .
```
- riscv64 on ubuntu 20.04
```
$ sudo apt-get install g++-riscv64-linux-gnu
$ cd CSerialPort
$ mkdir bin_riscv64 && cd bin_riscv64
$ cmake .. -DCMAKE_TOOLCHAIN_FILE=./cmake/toolchain_riscv64.cmake
$ cmake --build .
```
# Screenshot
## Gui
Demo Path: CSerialPort/examples/CommQT
![image](pic/linux.jpg)
## Tui
Demo Path: CSerialPort/examples/CommTui
![image](pic/linux_tui.jpg)
## No Gui
Demo Path: CSerialPort/examples/CommNoGui
![image](pic/linux_no_gui.jpg)
# Documents
[API Document](doc/CSerialPort_doc_en.chm)
[Directory List Document](doc/directory_list.md)
[Error Guide Document](doc/error_guide.md)
[Frequently Asked Questions](doc/FAQ.md)
# Contacting
- Email : itas109@qq.com
- QQ Group : [129518033](http://shang.qq.com/wpa/qunwpa?idkey=2888fa15c4513e6bfb9347052f36e437d919b2377161862948b2a49576679fc6)
# Links
- [CSDN Blog](https://blog.csdn.net/itas109)
- [Github](https://github.com/itas109/CSerialPort)
- [Gitee](https://gitee.com/itas109/CSerialPort)
# CSerialPort-based Applications
## 1. [CommMaster](https://gitee.com/itas109/CommMaster)
- support windows/linux/macos/raspberrypi and so on
- support custom port name
- support custom baudrate
- support custom language
- support custom theme
https://gitee.com/itas109/CommMaster
![image](pic/CommMaster.png)
## 2. [CommLite](https://github.com/itas109/CommLite)
CommLite is tui's serial port tool based CSerialPort
- support x86, arm, mips cpu architecture
- support windows dos, linux, macos,raspberrypi, freebsd operating system
https://github.com/itas109/CommLite
![image](pic/commlite.gif)
# Donate
[CSDN Blog](https://blog.csdn.net/itas109)
---
# Other branches
Only for windows branch : https://github.com/itas109/CSerialPort/tree/CSerialPort_win_3.0.3
Thanks for [Remon Spekreijse's serial library](http://www.codeguru.com/cpp/i-n/network/serialcommunications/article.php/c2483/A-communication-class-for-serial-port.htm)
---
# License
since V3.0.0.171216 use [GNU Lesser General Public License v3.0](LICENSE)

View File

@ -0,0 +1,231 @@
# [CSerialPort](https://github.com/itas109/CSerialPort)
[English](README.md)
CSerialPort是一个基于C/C++的轻量级开源跨平台串口类库可以轻松实现跨平台多操作系统的串口读写同时还支持C#, Java, Python, Node.js等。
<p>
<a href="https://github.com/itas109/CSerialPort/releases"><img alt="Version" src="https://img.shields.io/github/release/itas109/CSerialPort"/></a>
<a href="https://github.com/itas109/CSerialPort/stargazers"><img alt="Stars" src="https://img.shields.io/github/stars/itas109/CSerialPort"/></a>
<a href="https://gitee.com/itas109/CSerialPort"><img alt="Stars" src="https://gitee.com/itas109/CSerialPort/badge/star.svg?theme=dark"/></a>
<a href="https://github.com/itas109/CSerialPort/blob/master/LICENSE"><img alt="License" src="https://img.shields.io/badge/License-LGPL%203.0-orange"/></a>
<img alt="language" src="https://img.shields.io/badge/language-c++-red"/>
<img alt="appveyor-ci" src="https://ci.appveyor.com/api/projects/status/a4t6ddubhns561kh?svg=true"/>
<!-- <img alt="travis-ci" src="https://www.travis-ci.org/itas109/CSerialPort.svg?branch=master"/> -->
</p>
---
# Design Principles 设计原则
- 跨平台
- 简单易用
- 高效
# Platform 平台
CSerialPort已经在以下平台做过测试
- Windows ( x86, x86_64, arm64 )
- Linux ( x86, x86_64, arm, arm64/aarch64, mips64el, riscv, s390x, ppc64le )
- macOS ( x86_64 )
- Raspberry Pi ( armv7l )
- FreeBSD ( x86_64 )
- ...
# Todo List 待处理事项
## Long-term Goal 长期目标
- [x] 1.首先支持windows和linux平台
- [ ] 2.增加通用串口通信协议
- [x] 3.支持热插拔 - [CSerialPortExtend](https://github.com/itas109/CSerialPortExtend)
- [x] 4.更高效的通知模块 - CSerialPortListener
- [x] 5.支持其他语言 - C#, Python, Java, Node.js - 详见[bindings](https://github.com/itas109/CSerialPort/tree/master/bindings)
- [x] 6.同步串口通信
- [x] 7.全新的跨平台串口调试助手 - [CommMaster通信大师](https://gitee.com/itas109/CommMaster)
- [x] 8.增加CSerialPort的介绍和使用教程 - [CSerialPort教程](https://blog.csdn.net/itas109/category_12416341.html)
- [ ] 9.串口侦听hook
## Short-term Goal 短期目标
- [x] 1.跨平台操作系统识别库
- [x] 2.跨平台多线程类库
- [x] 3.跨平台锁类库
- [x] 4.跨平台高效定时器类库
- [ ] 5.跨平台线程池库
- [ ] 6.性能测试报告(吞吐量、时延、丢包率)
# Latest version 最新版本
## Version: 4.3.1.240204
by itas109 on 2024-02-04
# Quick Start 快速开始
```
$ git clone --depth=1 https://github.com/itas109/CSerialPort.git
$ cd CSerialPort
$ mkdir bin && cd bin
$ cmake ..
$ cmake --build .
```
运行示例程序(如linux下串口环回测试)
```
CSerialPort/bin $ ./CSerialPortDemoNoGui
Version: https://github.com/itas109/CSerialPort - V4.3.1.240204
AvailableFriendlyPorts:
1 - /dev/ttyUSB0 QinHeng CH340 serial converter 1a86:7523
2 - /dev/pts/0 0 pty terminal
Please Input The Index Of Port(1 - 2)
1
Port Name: /dev/ttyUSB0
[CSERIALPORT_DEBUG] openPort - portName: /dev/ttyUSB0, baudRate: 9600, dataBit: 8, parity: 0, stopBit: 0, flowControl: 0, mode: async, readBufferSize:4096(4096), readIntervalTimeoutMS: 0, minByteReadNotify: 1
[CSERIALPORT_DEBUG] openPort - open /dev/ttyUSB0. code: 0, message: success
Open /dev/ttyUSB0 Success
Code: 0, Message: success
[CSERIALPORT_DEBUG] writeData - write. len: 5, hex(top100): 3132333435
[CSERIALPORT_DEBUG] writeData - write. len: 7, hex(top100): 69746173313039
[CSERIALPORT_DEBUG] commThreadMonitor - write buffer(usedLen 12). len: 12, hex(top100): 313233343569746173313039
[CSERIALPORT_DEBUG] commThreadMonitor - onReadEvent. portName: /dev/ttyUSB0, readLen: 12
[CSERIALPORT_DEBUG] readData - read. len: 12, hex(top100): 313233343569746173313039
/dev/ttyUSB0 - Count: 1, Length: 12, Str: 12345itas109, Hex: 0x31 0x32 0x33 0x34 0x35 0x69 0x74 0x61 0x73 0x31 0x30 0x39
```
# Install CSerialPort Using Vcpkg 使用vcpkg安装CSerialPort
您可以通过[vcpkg](https://github.com/Microsoft/vcpkg/)依赖包管理工具下载和安装CSerialPort
```
$ git clone https://github.com/Microsoft/vcpkg.git
$ cd vcpkg
$ ./bootstrap-vcpkg.sh
$ ./vcpkg install cserialport
```
# Cross Compile 交叉编译
- arm on ubuntu 20.04
```
$ sudo apt-get install g++-arm-linux-gnueabi
$ cd CSerialPort
$ mkdir bin_arm && cd bin_arm
$ cmake .. -DCMAKE_TOOLCHAIN_FILE=./cmake/toolchain_arm.cmake
$ cmake --build .
```
- aarch64 on ubuntu 20.04
```
$ sudo apt-get install g++-aarch64-linux-gnu
$ cd CSerialPort
$ mkdir bin_aarch64 && cd bin_aarch64
$ cmake .. -DCMAKE_TOOLCHAIN_FILE=./cmake/toolchain_aarch64.cmake
$ cmake --build .
```
- mips64el on ubuntu 20.04
```
$ sudo apt-get install g++-mips64el-linux-gnuabi64
$ cd CSerialPort
$ mkdir bin_mips64el && cd bin_mips64el
$ cmake .. -DCMAKE_TOOLCHAIN_FILE=./cmake/toolchain_mips64el.cmake
$ cmake --build .
```
- riscv64 on ubuntu 20.04
```
$ sudo apt-get install g++-riscv64-linux-gnu
$ cd CSerialPort
$ mkdir bin_riscv64 && cd bin_riscv64
$ cmake .. -DCMAKE_TOOLCHAIN_FILE=./cmake/toolchain_riscv64.cmake
$ cmake --build .
```
# Screenshot 截图
## Gui 图形用户界面
示例路径: CSerialPort/examples/CommQT
![image](pic/linux.jpg)
## Tui 终端用户界面
示例路径: CSerialPort/examples/CommTui
![image](pic/linux_tui.jpg)
## No Gui 无界面
示例路径: CSerialPort/examples/CommNoGui
![image](pic/linux_no_gui.jpg)
# Documents 文档
[API接口文档](doc/CSerialPort_doc_cn.chm)
[目录列表文档](doc/directory_list.md)
[错误指南文档](doc/error_guide.md)
[常见问题回答](doc/FAQ.md)
# Contacting 联系方式
- Email : itas109@qq.com
- QQ群 : [129518033](http://shang.qq.com/wpa/qunwpa?idkey=2888fa15c4513e6bfb9347052f36e437d919b2377161862948b2a49576679fc6)
# Links 链接
- [CSDN博客](https://blog.csdn.net/itas109)
- [Github](https://github.com/itas109/CSerialPort)
- [Gitee码云](https://gitee.com/itas109/CSerialPort)
# CSerialPort-based Applications 基于CSerialPort的应用
## 1. [CommMaster通信大师](https://gitee.com/itas109/CommMaster)
- 支持windows/linux/macos/raspberrypi等等
- 支持自定义串口名称
- 支持自定义波特率
- 支持自定义语言
- 支持自定义主题
https://gitee.com/itas109/CommMaster
![image](pic/CommMaster.png)
## 2. [CommLite](https://github.com/itas109/CommLite)
CommLite是一款基于CSerialPort的文本UI串口调试助手
- 支持x86, arm, mips等cpu架构
- 支持windows dos, linux, macos, raspberrypi, freebsd等操作系统
https://github.com/itas109/CommLite
![image](pic/commlite.gif)
# Donate 捐助
[CSDN博客](https://blog.csdn.net/itas109)
---
# Other branches 其他分支
仅支持windows版本分支 : https://github.com/itas109/CSerialPort/tree/CSerialPort_win_3.0.3
非常感谢[Remon Spekreijse的串口通信库](http://www.codeguru.com/cpp/i-n/network/serialcommunications/article.php/c2483/A-communication-class-for-serial-port.htm)
---
# License 开源协议
自 V3.0.0.171216 版本后采用[GNU Lesser General Public License v3.0](LICENSE)

View File

@ -0,0 +1 @@
4.3.1.240204

View File

@ -0,0 +1,68 @@
#***************************************************************************
# @file appveyor.yml
# @author itas109 (itas109@qq.com) \n\n
# Blog : https://blog.csdn.net/itas109 \n
# Github : https://github.com/itas109 \n
# Gitee : https://gitee.com/itas109 \n
# QQ Group : 129518033
# @brief Lightweight cross-platform serial port library based on C++
# @copyright The CSerialPort is Copyright (C) 2014 itas109 <itas109@qq.com>.
# You may use, copy, modify, and distribute the CSerialPort, under the terms
# of the LICENSE file.
############################################################################
version: 1.0.{build}
image: Visual Studio 2015
clone_depth: 1
environment:
build_type: Release
matrix:
- compiler: msvc-14-win32
generator: Visual Studio 14 2015
build_test: ON
- compiler: msvc-14-win64
generator: Visual Studio 14 2015 Win64
build_test: ON
- compiler: msvc-14-win32-xp
generator: Visual Studio 14 2015
platformset: v140_xp
- compiler: msvc-12-win32
generator: Visual Studio 12 2013
- compiler: msvc-12-win64
generator: Visual Studio 12 2013 Win64
- compiler: msvc-11-win32
generator: Visual Studio 11 2012
- compiler: msvc-11-win64
generator: Visual Studio 11 2012 Win64
- compiler: msvc-10-win32
generator: Visual Studio 10 2010
- compiler: msvc-08-win32
generator: Visual Studio 9 2008
- compiler: mingw-4.9.2-posix-win32
generator: MinGW Makefiles
cxx_path: C:\Qt\Tools\mingw492_32\bin
- compiler: mingw-5.3.0-posix-win32
generator: MinGW Makefiles
cxx_path: C:\mingw-w64\i686-5.3.0-posix-dwarf-rt_v4-rev0\mingw32\bin
- compiler: mingw-7.3.0-posix-win64
generator: MinGW Makefiles
cxx_path: C:\mingw-w64\x86_64-7.3.0-posix-seh-rt_v5-rev0\mingw64\bin
install:
- ps: "# git bash conflicts with MinGW makefiles\nif ($env:generator -eq \"MinGW Makefiles\") \n{\n $env:path = $env:path.replace(\"C:\\Program Files\\Git\\usr\\bin;\", \"\")\n if ($env:cxx_path -ne \"\") \n {\n $env:path = \"$env:cxx_path;\" + $env:path\n }\n}\n\n\nWrite-Output \"APPVEYOR_BUILD_FOLDER: $env:APPVEYOR_BUILD_FOLDER\"\nWrite-Output \"Compiler: $env:compiler\"\nWrite-Output \"Generator: $env:generator\"\n# Write-Output \"Path: $env:path\"\nWrite-Output \"Env:build_type: $env:build_type\""
build_script:
- ps: "cd $env:APPVEYOR_BUILD_FOLDER\n\nmkdir bin\n\ncd bin\n\nif ($env:build_test -ne \"ON\") \n{\n $env:build_test=\"OFF\"\n}\n\nif ($env:platformset -ne \"\") \n{\n cmake -G \"$env:generator\" -DCSERIALPORT_BUILD_TEST=\"$env:build_test\" -DCMAKE_BUILD_TYPE=\"$env:build_type\" .. \n}\nelse\n{\n cmake -G \"$env:generator\" -T \"$env:platformset\" -DCSERIALPORT_BUILD_TEST=\"$env:build_test\" -DCMAKE_BUILD_TYPE=\"$env:build_type\" .. \n}\n\ncmake --build ."
test_script:
- ps: >-
if ($env:build_test -eq "ON")
{
cd $env:APPVEYOR_BUILD_FOLDER
bin\bin\Debug\CSerialPortTest.exe
}
notifications:
- provider: Email
to:
- itas109@qq.com
on_build_success: true
on_build_failure: true
on_build_status_changed: true

View File

@ -0,0 +1,48 @@
#***************************************************************************
# @file CMakeLists.txt
# @author itas109 (itas109@qq.com) \n\n
# Blog : https://blog.csdn.net/itas109 \n
# Github : https://github.com/itas109 \n
# Gitee : https://gitee.com/itas109 \n
# QQ Group : 129518033
# @brief Lightweight cross-platform serial port library based on C++
# @copyright The CSerialPort is Copyright (C) 2014 itas109 <itas109@qq.com>.
# You may use, copy, modify, and distribute the CSerialPort, under the terms
# of the LICENSE file.
############################################################################
cmake_minimum_required(VERSION 3.8.2)
project(cserialport)
# add_definitions(-DCSERIALPORT_DEBUG) # CSerialPort Debug Mode
# set output directory
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
# cserialport files
set(CSerialPortRootPath "${CMAKE_CURRENT_SOURCE_DIR}/../..")
include_directories(${CSerialPortRootPath}/include)
list(APPEND CSerialPortSourceFiles ${CSerialPortRootPath}/src/SerialPort.cpp ${CSerialPortRootPath}/src/SerialPortBase.cpp ${CSerialPortRootPath}/src/SerialPortInfo.cpp ${CSerialPortRootPath}/src/SerialPortInfoBase.cpp)
if (WIN32)
list(APPEND CSerialPortSourceFiles ${CSerialPortRootPath}/src/SerialPortInfoWinBase.cpp ${CSerialPortRootPath}/src/SerialPortWinBase.cpp)
list(APPEND CSerialPortSourceFiles ${CSerialPortRootPath}/lib/version.rc)
elseif (UNIX)
list(APPEND CSerialPortSourceFiles ${CSerialPortRootPath}/src/SerialPortInfoUnixBase.cpp ${CSerialPortRootPath}/src/SerialPortUnixBase.cpp)
endif ()
add_library(${PROJECT_NAME} SHARED cserialport.cpp ${CSerialPortSourceFiles})
if (WIN32)
target_link_libraries(${PROJECT_NAME} setupapi)
elseif (APPLE)
find_library(IOKIT_LIBRARY IOKit)
find_library(FOUNDATION_LIBRARY Foundation)
target_link_libraries(${PROJECT_NAME} ${FOUNDATION_LIBRARY} ${IOKIT_LIBRARY})
elseif (UNIX)
target_link_libraries(${PROJECT_NAME} pthread)
endif ()
# example
add_subdirectory(example)

View File

@ -0,0 +1,63 @@
# CSerialPort for C
```
cmake: 3.8.2
```
## Install cmake
### windows
- cmake
```
$ wget https://github.com/Kitware/CMake/releases/download/v3.26.4/cmake-3.26.4-windows-x86_64.msi
```
### linux
- cmake
```
$ wget https://github.com/Kitware/CMake/releases/download/v3.26.4/cmake-3.26.4-linux-x86_64.sh
$ sudo ./cmake-3.26.4-linux-x86_64.sh --prefix=/usr/local --skip-license
$ cmake --version
cmake version 3.26.4
```
## Build
```
cd c
mkdir bin
cd bin
cmake ..
cmake --build .
```
## Run
```
cd bin
CommC
```
### Tree
```
bindings/c $tree
.
+--- bin
| +--- bin
| | +--- Debug
| | | +--- CommC.exe
| | | +--- cserialport.dll
+--- CMakeLists.txt
+--- cserialport.cpp
+--- cserialport.h
+--- example
| +--- CMakeLists.txt
| +--- main.c
+--- README.md
```

View File

@ -0,0 +1,476 @@
#include "cserialport.h"
#include "CSerialPort/SerialPort.h"
#include "CSerialPort/SerialPortInfo.h"
#include "CSerialPort/iutils.hpp"
#include <vector>
class CSPListener : public itas109::CSerialPortListener
{
public:
CSPListener(void *pSerialPort, pFunReadEvent pFun)
: m_pSerialPort(pSerialPort)
, m_pFun(pFun){};
void onReadEvent(const char *portName, unsigned int readBufferLen)
{
m_pFun(m_pSerialPort, portName, readBufferLen);
};
private:
void *m_pSerialPort;
pFunReadEvent m_pFun;
};
void CSerialPortAvailablePortInfos(SerialPortInfoArray *portInfoArray)
{
std::vector<itas109::SerialPortInfo> portInfos = itas109::CSerialPortInfo::availablePortInfos();
portInfoArray->size = static_cast<unsigned int>(portInfos.size());
if (portInfoArray->size > 0)
{
portInfoArray->portInfo = new SerialPortInfo[portInfoArray->size];
for (unsigned int i = 0; i < portInfoArray->size; ++i)
{
itas109::IUtils::strncpy(portInfoArray->portInfo[i].portName, portInfos[i].portName, 256);
itas109::IUtils::strncpy(portInfoArray->portInfo[i].description, portInfos[i].description, 256);
itas109::IUtils::strncpy(portInfoArray->portInfo[i].hardwareId, portInfos[i].hardwareId, 256);
}
}
else
{
portInfoArray->portInfo = nullptr;
}
}
void CSerialPortAvailablePortInfosFree(struct SerialPortInfoArray *portInfoArray)
{
if (portInfoArray)
{
delete[] portInfoArray->portInfo;
portInfoArray->portInfo = nullptr;
portInfoArray->size = 0;
}
}
void *CSerialPortMalloc()
{
return new itas109::CSerialPort();
}
void CSerialPortFree(void *pSerialPort)
{
itas109::CSerialPort *pCSP = reinterpret_cast<itas109::CSerialPort *>(pSerialPort);
if (pCSP)
{
delete pCSP;
pCSP = nullptr;
}
}
void CSerialPortInit(void *pSerialPort,
const char *portName,
int baudRate,
Parity parity,
DataBits dataBits,
StopBits stopbits,
FlowControl flowControl,
unsigned int readBufferSize)
{
itas109::CSerialPort *pCSP = reinterpret_cast<itas109::CSerialPort *>(pSerialPort);
if (pCSP)
{
pCSP->init(portName, baudRate, itas109::Parity(parity), itas109::DataBits(dataBits), itas109::StopBits(stopbits), itas109::FlowControl(flowControl), readBufferSize);
}
}
void CSerialPortSetOperateMode(void *pSerialPort, OperateMode operateMode)
{
itas109::CSerialPort *pCSP = reinterpret_cast<itas109::CSerialPort *>(pSerialPort);
if (pCSP)
{
pCSP->setOperateMode(itas109::OperateMode(operateMode));
}
}
int CSerialPortOpen(void *pSerialPort)
{
itas109::CSerialPort *pCSP = reinterpret_cast<itas109::CSerialPort *>(pSerialPort);
if (pCSP)
{
return pCSP->open();
}
return 0;
}
void CSerialPortClose(void *pSerialPort)
{
itas109::CSerialPort *pCSP = reinterpret_cast<itas109::CSerialPort *>(pSerialPort);
if (pCSP)
{
pCSP->close();
}
}
int CSerialPortIsOpen(void *pSerialPort)
{
itas109::CSerialPort *pCSP = reinterpret_cast<itas109::CSerialPort *>(pSerialPort);
if (pCSP)
{
return pCSP->isOpen();
}
return 0;
}
int CSerialPortConnectReadEvent(void *pSerialPort, pFunReadEvent pFun)
{
itas109::CSerialPort *pCSP = reinterpret_cast<itas109::CSerialPort *>(pSerialPort);
if (pCSP)
{
// TODO: delete new CSPListener
CSPListener *listen = new CSPListener(pSerialPort, pFun);
return pCSP->connectReadEvent(listen);
}
return -1;
}
int CSerialPortDisconnectReadEvent(void *pSerialPort)
{
itas109::CSerialPort *pCSP = reinterpret_cast<itas109::CSerialPort *>(pSerialPort);
if (pCSP)
{
return pCSP->disconnectReadEvent();
}
return -1;
}
unsigned int CSerialPortGetReadBufferUsedLen(void *pSerialPort)
{
itas109::CSerialPort *pCSP = reinterpret_cast<itas109::CSerialPort *>(pSerialPort);
if (pCSP)
{
return pCSP->getReadBufferUsedLen();
}
return 0;
}
int CSerialPortReadData(void *pSerialPort, void *data, int size)
{
itas109::CSerialPort *pCSP = reinterpret_cast<itas109::CSerialPort *>(pSerialPort);
if (pCSP)
{
return pCSP->readData(data, size);
}
return -1;
}
int CSerialPortReadAllData(void *pSerialPort, void *data)
{
itas109::CSerialPort *pCSP = reinterpret_cast<itas109::CSerialPort *>(pSerialPort);
if (pCSP)
{
return pCSP->readAllData(data);
}
return -1;
}
int CSerialPortReadLineData(void *pSerialPort, void *data, int size)
{
itas109::CSerialPort *pCSP = reinterpret_cast<itas109::CSerialPort *>(pSerialPort);
if (pCSP)
{
return pCSP->readLineData(data, size);
}
return -1;
}
int CSerialPortWriteData(void *pSerialPort, const void *data, int size)
{
itas109::CSerialPort *pCSP = reinterpret_cast<itas109::CSerialPort *>(pSerialPort);
if (pCSP)
{
return pCSP->writeData(data, size);
}
return -1;
}
void CSerialPortSetDebugModel(void *pSerialPort, int isDebug)
{
itas109::CSerialPort *pCSP = reinterpret_cast<itas109::CSerialPort *>(pSerialPort);
if (pCSP)
{
pCSP->setDebugModel(isDebug);
}
}
void CSerialPortSetReadIntervalTimeout(void *pSerialPort, unsigned int msecs)
{
itas109::CSerialPort *pCSP = reinterpret_cast<itas109::CSerialPort *>(pSerialPort);
if (pCSP)
{
pCSP->setReadIntervalTimeout(msecs);
}
}
unsigned int CSerialPortGetReadIntervalTimeout(void *pSerialPort)
{
itas109::CSerialPort *pCSP = reinterpret_cast<itas109::CSerialPort *>(pSerialPort);
if (pCSP)
{
return pCSP->getReadIntervalTimeout();
}
return 0;
}
void CSerialPortSetMinByteReadNotify(void *pSerialPort, unsigned int minByteReadNotify)
{
itas109::CSerialPort *pCSP = reinterpret_cast<itas109::CSerialPort *>(pSerialPort);
if (pCSP)
{
pCSP->setMinByteReadNotify(minByteReadNotify);
}
}
int CSerialPortFlushBuffers(void *pSerialPort)
{
itas109::CSerialPort *pCSP = reinterpret_cast<itas109::CSerialPort *>(pSerialPort);
if (pCSP)
{
pCSP->flushBuffers();
}
return 0;
}
int CSerialPortFlushReadBuffers(void *pSerialPort)
{
itas109::CSerialPort *pCSP = reinterpret_cast<itas109::CSerialPort *>(pSerialPort);
if (pCSP)
{
pCSP->flushReadBuffers();
}
return 0;
}
int CSerialPortFlushWriteBuffers(void *pSerialPort)
{
itas109::CSerialPort *pCSP = reinterpret_cast<itas109::CSerialPort *>(pSerialPort);
if (pCSP)
{
return pCSP->flushWriteBuffers();
}
return 0;
}
int CSerialPortGetLastError(void *pSerialPort)
{
itas109::CSerialPort *pCSP = reinterpret_cast<itas109::CSerialPort *>(pSerialPort);
if (pCSP)
{
return pCSP->getLastError();
}
return 0;
}
const char *CSerialPortGetLastErrorMsg(void *pSerialPort)
{
itas109::CSerialPort *pCSP = reinterpret_cast<itas109::CSerialPort *>(pSerialPort);
if (pCSP)
{
return pCSP->getLastErrorMsg();
}
return "";
}
void CSerialPortClearError(void *pSerialPort)
{
itas109::CSerialPort *pCSP = reinterpret_cast<itas109::CSerialPort *>(pSerialPort);
if (pCSP)
{
pCSP->clearError();
}
}
void CSerialPortSetPortName(void *pSerialPort, const char *portName)
{
itas109::CSerialPort *pCSP = reinterpret_cast<itas109::CSerialPort *>(pSerialPort);
if (pCSP)
{
pCSP->setPortName(portName);
}
}
const char *CSerialPortGetPortName(void *pSerialPort)
{
itas109::CSerialPort *pCSP = reinterpret_cast<itas109::CSerialPort *>(pSerialPort);
if (pCSP)
{
return pCSP->getPortName();
}
return "";
}
void CSerialPortSetBaudRate(void *pSerialPort, int baudRate)
{
itas109::CSerialPort *pCSP = reinterpret_cast<itas109::CSerialPort *>(pSerialPort);
if (pCSP)
{
pCSP->setBaudRate(baudRate);
}
}
int CSerialPortGetBaudRate(void *pSerialPort)
{
itas109::CSerialPort *pCSP = reinterpret_cast<itas109::CSerialPort *>(pSerialPort);
if (pCSP)
{
return pCSP->getBaudRate();
}
return 0;
}
void CSerialPortSetParity(void *pSerialPort, Parity parity)
{
itas109::CSerialPort *pCSP = reinterpret_cast<itas109::CSerialPort *>(pSerialPort);
if (pCSP)
{
pCSP->setParity(itas109::Parity(parity));
}
}
Parity CSerialPortGetParity(void *pSerialPort)
{
itas109::CSerialPort *pCSP = reinterpret_cast<itas109::CSerialPort *>(pSerialPort);
if (pCSP)
{
return Parity(pCSP->getParity());
}
return ParityNone;
}
void CSerialPortSetDataBits(void *pSerialPort, DataBits dataBits)
{
itas109::CSerialPort *pCSP = reinterpret_cast<itas109::CSerialPort *>(pSerialPort);
if (pCSP)
{
pCSP->setDataBits(itas109::DataBits(dataBits));
}
}
DataBits CSerialPortGetDataBits(void *pSerialPort)
{
itas109::CSerialPort *pCSP = reinterpret_cast<itas109::CSerialPort *>(pSerialPort);
if (pCSP)
{
return DataBits(pCSP->getDataBits());
}
return DataBits8;
}
void CSerialPortSetStopBits(void *pSerialPort, StopBits stopbits)
{
itas109::CSerialPort *pCSP = reinterpret_cast<itas109::CSerialPort *>(pSerialPort);
if (pCSP)
{
pCSP->setStopBits(itas109::StopBits(stopbits));
}
}
StopBits CSerialPortGetStopBits(void *pSerialPort)
{
itas109::CSerialPort *pCSP = reinterpret_cast<itas109::CSerialPort *>(pSerialPort);
if (pCSP)
{
return StopBits(pCSP->getStopBits());
}
return StopOne;
}
void CSerialPortSetFlowControl(void *pSerialPort, FlowControl flowControl)
{
itas109::CSerialPort *pCSP = reinterpret_cast<itas109::CSerialPort *>(pSerialPort);
if (pCSP)
{
pCSP->setFlowControl(itas109::FlowControl(flowControl));
}
}
FlowControl CSerialPortGetFlowControl(void *pSerialPort)
{
itas109::CSerialPort *pCSP = reinterpret_cast<itas109::CSerialPort *>(pSerialPort);
if (pCSP)
{
return FlowControl(pCSP->getFlowControl());
}
return FlowNone;
}
void CSerialPortSetReadBufferSize(void *pSerialPort, unsigned int size)
{
itas109::CSerialPort *pCSP = reinterpret_cast<itas109::CSerialPort *>(pSerialPort);
if (pCSP)
{
pCSP->setReadBufferSize(size);
}
}
unsigned int CSerialPortGetReadBufferSize(void *pSerialPort)
{
itas109::CSerialPort *pCSP = reinterpret_cast<itas109::CSerialPort *>(pSerialPort);
if (pCSP)
{
return pCSP->getReadBufferSize();
}
return 0;
}
void CSerialPortSetDtr(void *pSerialPort, int set)
{
itas109::CSerialPort *pCSP = reinterpret_cast<itas109::CSerialPort *>(pSerialPort);
if (pCSP)
{
pCSP->setDtr(set);
}
}
void CSerialPortSetRts(void *pSerialPort, int set)
{
itas109::CSerialPort *pCSP = reinterpret_cast<itas109::CSerialPort *>(pSerialPort);
if (pCSP)
{
pCSP->setRts(set);
}
}
const char *CSerialPortGetVersion(void *pSerialPort)
{
itas109::CSerialPort *pCSP = reinterpret_cast<itas109::CSerialPort *>(pSerialPort);
if (pCSP)
{
return pCSP->getVersion();
}
return "";
}

View File

@ -0,0 +1,206 @@
#ifndef __C_CSERIALPORT_H__
#define __C_CSERIALPORT_H__
#ifdef _WIN32
#define C_DLL_EXPORT __declspec(dllexport)
#else
#define C_DLL_EXPORT
#endif
struct SerialPortInfo
{
char portName[256];
char description[256];
char hardwareId[256];
};
struct SerialPortInfoArray
{
struct SerialPortInfo *portInfo;
unsigned int size;
};
enum OperateMode
{
AsynchronousOperate,
SynchronousOperate
};
enum BaudRate
{
BaudRate110 = 110,
BaudRate300 = 300,
BaudRate600 = 600,
BaudRate1200 = 1200,
BaudRate2400 = 2400,
BaudRate4800 = 4800,
BaudRate9600 = 9600,
BaudRate14400 = 14400,
BaudRate19200 = 19200,
BaudRate38400 = 38400,
BaudRate56000 = 56000,
BaudRate57600 = 57600,
BaudRate115200 = 115200,
BaudRate921600 = 921600
};
enum DataBits
{
DataBits5 = 5,
DataBits6 = 6,
DataBits7 = 7,
DataBits8 = 8
};
enum Parity
{
ParityNone = 0,
ParityOdd = 1,
ParityEven = 2,
ParityMark = 3,
ParitySpace = 4,
};
enum StopBits
{
StopOne = 0,
StopOneAndHalf = 1,
StopTwo = 2
};
enum FlowControl
{
FlowNone = 0,
FlowHardware = 1,
FlowSoftware = 2
};
enum SerialPortError
{
ErrorUnknown = -1,
ErrorOK = 0,
ErrorFail = 1,
ErrorNotImplemented,
ErrorInner,
ErrorNullPointer,
ErrorInvalidParam,
ErrorAccessDenied,
ErrorOutOfMemory,
ErrorTimeout,
ErrorNotInit,
ErrorInitFailed,
ErrorAlreadyExist,
ErrorNotExist,
ErrorAlreadyOpen,
ErrorNotOpen,
ErrorOpenFailed,
ErrorCloseFailed,
ErrorWriteFailed,
ErrorReadFailed
};
#ifdef __cplusplus
extern "C"
{
#endif
typedef void (*pFunReadEvent)(void * /*pSerialPort*/, const char * /*portName*/, unsigned int /*readBufferLen*/);
C_DLL_EXPORT void CSerialPortAvailablePortInfos(struct SerialPortInfoArray *portInfoArray);
C_DLL_EXPORT void CSerialPortAvailablePortInfosFree(struct SerialPortInfoArray *portInfoArray);
C_DLL_EXPORT void *CSerialPortMalloc();
C_DLL_EXPORT void CSerialPortFree(void *pSerialPort);
C_DLL_EXPORT void CSerialPortInit(void *pSerialPort,
const char *portName,
int baudRate,
enum Parity parity,
enum DataBits dataBits,
enum StopBits stopbits,
enum FlowControl flowControl,
unsigned int readBufferSize);
C_DLL_EXPORT void CSerialPortSetOperateMode(void *pSerialPort, enum OperateMode operateMode);
C_DLL_EXPORT int CSerialPortOpen(void *pSerialPort);
C_DLL_EXPORT void CSerialPortClose(void *pSerialPort);
C_DLL_EXPORT int CSerialPortIsOpen(void *pSerialPort);
C_DLL_EXPORT int CSerialPortConnectReadEvent(void *pSerialPort, pFunReadEvent pFun);
C_DLL_EXPORT int CSerialPortDisconnectReadEvent(void *pSerialPort);
C_DLL_EXPORT unsigned int CSerialPortGetReadBufferUsedLen(void *pSerialPort);
C_DLL_EXPORT int CSerialPortReadData(void *pSerialPort, void *data, int size);
C_DLL_EXPORT int CSerialPortReadAllData(void *pSerialPort, void *data);
C_DLL_EXPORT int CSerialPortReadLineData(void *pSerialPort, void *data, int size);
C_DLL_EXPORT int CSerialPortWriteData(void *pSerialPort, const void *data, int size);
C_DLL_EXPORT void CSerialPortSetDebugModel(void *pSerialPort, int isDebug);
C_DLL_EXPORT void CSerialPortSetReadIntervalTimeout(void *pSerialPort, unsigned int msecs);
C_DLL_EXPORT unsigned int CSerialPortGetReadIntervalTimeout(void *pSerialPort);
C_DLL_EXPORT void CSerialPortSetMinByteReadNotify(void *pSerialPort, unsigned int minByteReadNotify);
C_DLL_EXPORT int CSerialPortFlushBuffers(void *pSerialPort);
C_DLL_EXPORT int CSerialPortFlushReadBuffers(void *pSerialPort);
C_DLL_EXPORT int CSerialPortFlushWriteBuffers(void *pSerialPort);
C_DLL_EXPORT int CSerialPortGetLastError(void *pSerialPort);
C_DLL_EXPORT const char *CSerialPortGetLastErrorMsg(void *pSerialPort);
C_DLL_EXPORT void CSerialPortClearError(void *pSerialPort);
C_DLL_EXPORT void CSerialPortSetPortName(void *pSerialPort, const char *portName);
C_DLL_EXPORT const char *CSerialPortGetPortName(void *pSerialPort);
C_DLL_EXPORT void CSerialPortSetBaudRate(void *pSerialPort, int baudRate);
C_DLL_EXPORT int CSerialPortGetBaudRate(void *pSerialPort);
C_DLL_EXPORT void CSerialPortSetParity(void *pSerialPort, enum Parity parity);
C_DLL_EXPORT enum Parity CSerialPortGetParity(void *pSerialPort);
C_DLL_EXPORT void CSerialPortSetDataBits(void *pSerialPort, enum DataBits dataBits);
C_DLL_EXPORT enum DataBits CSerialPortGetDataBits(void *pSerialPort);
C_DLL_EXPORT void CSerialPortSetStopBits(void *pSerialPort, enum StopBits stopbits);
C_DLL_EXPORT enum StopBits CSerialPortGetStopBits(void *pSerialPort);
C_DLL_EXPORT void CSerialPortSetFlowControl(void *pSerialPort, enum FlowControl flowControl);
C_DLL_EXPORT enum FlowControl CSerialPortGetFlowControl(void *pSerialPort);
C_DLL_EXPORT void CSerialPortSetReadBufferSize(void *pSerialPort, unsigned int size);
C_DLL_EXPORT unsigned int CSerialPortGetReadBufferSize(void *pSerialPort);
C_DLL_EXPORT void CSerialPortSetDtr(void *pSerialPort, int set);
C_DLL_EXPORT void CSerialPortSetRts(void *pSerialPort, int set);
C_DLL_EXPORT const char *CSerialPortGetVersion(void *pSerialPort);
#ifdef __cplusplus
}
#endif
#endif // !__C_CSERIALPORT_H__

View File

@ -0,0 +1,21 @@
#***************************************************************************
# @file CMakeLists.txt
# @author itas109 (itas109@qq.com) \n\n
# Blog : https://blog.csdn.net/itas109 \n
# Github : https://github.com/itas109 \n
# Gitee : https://gitee.com/itas109 \n
# QQ Group : 129518033
# @brief Lightweight cross-platform serial port library based on C++
# @copyright The CSerialPort is Copyright (C) 2014 itas109 <itas109@qq.com>.
# You may use, copy, modify, and distribute the CSerialPort, under the terms
# of the LICENSE file.
############################################################################
cmake_minimum_required(VERSION 3.8.2)
project(CommC)
include_directories(../) # cserialport.h
add_executable(${PROJECT_NAME} main.c)
target_link_libraries(${PROJECT_NAME} cserialport)

View File

@ -0,0 +1,155 @@
/**
* @file main.c
* @author itas109 (itas109@qq.com) \n\n
* Blog : https://blog.csdn.net/itas109 \n
* Github : https://github.com/itas109 \n
* Gitee : https://gitee.com/itas109 \n
* QQ Group : 129518033
* @brief C CSerialPort Example C的CSerialPort示例程序
*/
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include "cserialport.h"
int countRead = 0;
void char2hexstr(char *dest, const char *src, int len)
{
static const char hexTable[17] = "0123456789ABCDEF";
for (int i = 0; i < len; ++i)
{
// 0x + two bit hex + one bit space => 5 bit
dest[5 * i + 0] = '0';
dest[5 * i + 1] = 'x';
dest[5 * i + 2] = hexTable[(unsigned char)src[i] / 16];
dest[5 * i + 3] = hexTable[(unsigned char)src[i] % 16];
dest[5 * i + 4] = ' ';
}
dest[5 * len] = '\0';
}
void onReadEvent(void *pSerialPort, const char *portName, unsigned int readBufferLen)
{
if (readBufferLen > 0)
{
char *data = malloc(readBufferLen + 1); // '\0'
if (data)
{
// read
int recLen = CSerialPortReadData(pSerialPort, data, readBufferLen);
if (recLen > 0)
{
data[recLen] = '\0';
char *hexStr = malloc(5 * recLen + 1);
char2hexstr(hexStr, data, recLen);
printf("%s - Count: %d Length: %d, Str: %s, Hex: %s\n", portName, ++countRead, recLen, data, hexStr);
if (hexStr)
{
free(hexStr);
hexStr = NULL;
}
// return receive data
CSerialPortWriteData(pSerialPort, data, recLen);
}
free(data);
data = NULL;
}
}
}
int main()
{
void *pSerialPort = NULL;
pSerialPort = CSerialPortMalloc();
printf("Version: %s\n\n", CSerialPortGetVersion(pSerialPort));
printf("Available Friendly Ports:\n");
struct SerialPortInfoArray portInfoArray = {0};
CSerialPortAvailablePortInfos(&portInfoArray);
for (unsigned int i = 0; i < portInfoArray.size; ++i)
{
printf("%u - %s %s\n", i + 1, portInfoArray.portInfo[i].portName, portInfoArray.portInfo[i].description);
}
if (portInfoArray.size == 0)
{
printf("No Valid Port\n");
}
else
{
printf("\n");
unsigned int input = 0;
do
{
printf("Please Input The Index Of Port(1 - %d)\n", portInfoArray.size);
scanf("%u", &input);
if (input >= 1 && input <= portInfoArray.size)
{
break;
}
} while (1);
char portName[256] = {0};
strcpy(portName, portInfoArray.portInfo[input - 1].portName);
printf("Port Name: %s\n", portName);
CSerialPortAvailablePortInfosFree(&portInfoArray);
CSerialPortInit(pSerialPort,
portName, // windows:COM1 Linux:/dev/ttyS0
9600, // baudrate
ParityNone, // parity
DataBits8, // data bit
StopOne, // stop bit
FlowNone, // flow
4096 // read buffer size
);
CSerialPortSetReadIntervalTimeout(pSerialPort, 0); // read interval timeout
CSerialPortOpen(pSerialPort);
printf("Open %s %s\n", portName, 1 == CSerialPortIsOpen(pSerialPort) ? "Success" : "Failed");
printf("Code: %d, Message: %s\n", CSerialPortGetLastError(pSerialPort), CSerialPortGetLastErrorMsg(pSerialPort));
// connect for read
CSerialPortConnectReadEvent(pSerialPort, onReadEvent);
// write hex data
char hex[5];
hex[0] = 0x31;
hex[1] = 0x32;
hex[2] = 0x33;
hex[3] = 0x34;
hex[4] = 0x35;
CSerialPortWriteData(pSerialPort, hex, sizeof(hex));
// write str data
CSerialPortWriteData(pSerialPort, "itas109", 7);
}
for (;;)
{
}
CSerialPortDisconnectReadEvent(pSerialPort);
CSerialPortFree(pSerialPort);
return 0;
}

View File

@ -0,0 +1,48 @@
#***************************************************************************
# @file CMakeLists.txt
# @author itas109 (itas109@qq.com) \n\n
# Blog : https://blog.csdn.net/itas109 \n
# Github : https://github.com/itas109 \n
# Gitee : https://gitee.com/itas109 \n
# QQ Group : 129518033
# @brief Lightweight cross-platform serial port library based on C++
# @copyright The CSerialPort is Copyright (C) 2014 itas109 <itas109@qq.com>.
# You may use, copy, modify, and distribute the CSerialPort, under the terms
# of the LICENSE file.
############################################################################
cmake_minimum_required(VERSION 3.8.2)
project(cserialport)
# set output directory
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
# cserialport files
set(CSerialPortRootPath "${CMAKE_CURRENT_SOURCE_DIR}/../..")
include_directories(${CSerialPortRootPath}/include)
list(APPEND CSerialPortSourceFiles ${CSerialPortRootPath}/src/SerialPort.cpp ${CSerialPortRootPath}/src/SerialPortBase.cpp ${CSerialPortRootPath}/src/SerialPortInfo.cpp ${CSerialPortRootPath}/src/SerialPortInfoBase.cpp)
if (WIN32)
list(APPEND CSerialPortSourceFiles ${CSerialPortRootPath}/src/SerialPortInfoWinBase.cpp ${CSerialPortRootPath}/src/SerialPortWinBase.cpp)
list(APPEND CSerialPortSourceFiles ${CSerialPortRootPath}/lib/version.rc)
elseif (UNIX)
list(APPEND CSerialPortSourceFiles ${CSerialPortRootPath}/src/SerialPortInfoUnixBase.cpp ${CSerialPortRootPath}/src/SerialPortUnixBase.cpp)
endif ()
# find swig
find_package(SWIG REQUIRED)
include(${SWIG_USE_FILE})
# swig -outdir option(*.cs xxx_wrap.cxx xxx_wrap.h)
set(CMAKE_SWIG_OUTDIR "${CMAKE_CURRENT_SOURCE_DIR}/generate")
# call swig in c++ mode
set_property(SOURCE cserialport.i PROPERTY CPLUSPLUS ON)
# set namespace
set(CMAKE_SWIG_FLAGS -namespace itas109)
# swig -csharp -c++ -outdir generate -I../../include -namespace itas109 cserialport.i
swig_add_library(${PROJECT_NAME} LANGUAGE csharp SOURCES cserialport.i ${CSerialPortSourceFiles})
# example
add_subdirectory(example)

View File

@ -0,0 +1,112 @@
# CSerialPort for CSharp
```
swig: 4.1.1 (2022-11-30)
cmake: 3.8.2
```
## Install swig && cmake
### windows
- swig
```
$ wget https://sourceforge.net/projects/swig/files/swigwin/swigwin-4.1.1/swigwin-4.1.1.zip
```
- cmake
```
$ wget https://github.com/Kitware/CMake/releases/download/v3.26.4/cmake-3.26.4-windows-x86_64.msi
```
### linux
- swig
```
$ wget https://sourceforge.net/projects/swig/files/swig/swig-4.1.1/swig-4.1.1.tar.gz
$ tar zxvf swig-4.1.1.tar.gz
$ cd swig-4.1.1
$ ./configure --without-pcre
$ make
$ sudo make install
$ swig -version
SWIG Version 4.1.1
```
- cmake
```
$ wget https://github.com/Kitware/CMake/releases/download/v3.26.4/cmake-3.26.4-linux-x86_64.sh
$ sudo ./cmake-3.26.4-linux-x86_64.sh --prefix=/usr/local --skip-license
$ cmake --version
cmake version 3.26.4
```
## Build
```
cd csharp
mkdir bin
cd bin
cmake .. -DSWIG_EXECUTABLE=D:/swigwin-4.1.1/swig.exe
cmake --build .
```
**Notice:**
```
D:/swigwin-4.1.1/swig.exe should replace with your path to swig.exe
```
or (config swig to path)
```
set path=D:/swigwin-4.1.1;%path%
cmake ..
```
## Run
```
cd bin
CommCSharp
```
### Tree
```
bindings/csharp $tree
.
+--- bin
| +--- bin
| | +--- Debug
| | | +--- CommCSharp.exe
| | | +--- cserialport.dll
+--- CMakeLists.txt
+--- cserialport.i
+--- example
| +--- CMakeLists.txt
| +--- Program.cs
+--- generate
| +--- BaudRate.cs
| +--- CSerialPort.cs
| +--- cserialportCSharp.cs
| +--- cserialportCSharpPINVOKE.cs
| +--- cserialportCSHARP_wrap.cxx
| +--- cserialportCSHARP_wrap.h
| +--- CSerialPortInfo.cs
| +--- CSerialPortListener.cs
| +--- DataBits.cs
| +--- FlowControl.cs
| +--- OperateMode.cs
| +--- Parity.cs
| +--- SerialPortError.cs
| +--- SerialPortInfo.cs
| +--- SerialPortInfoVector.cs
| +--- StopBits.cs
+--- README.md
```

View File

@ -0,0 +1,36 @@
/**
* @file cserialport.i
* @author itas109 (itas109@qq.com) \n\n
* Blog : https://blog.csdn.net/itas109 \n
* Github : https://github.com/itas109 \n
* Gitee : https://gitee.com/itas109 \n
* QQ Group : 129518033
* SWIG: 4.1.0
* @brief CSharp CSerialPort Interface C#CSerialPort
*/
/* File : cserialport.i */
%module(directors="1") cserialportCSharp
#define DLL_EXPORT
%{
#include "CSerialPort/SerialPort_global.h"
#include "CSerialPort/SerialPort.h"
#include "CSerialPort/SerialPortListener.h"
#include "CSerialPort/SerialPortInfo.h"
%}
%include "std_vector.i" // std::vector
%include "arrays_csharp.i" // typemaps for csharp
%apply unsigned char INPUT[] {void *} // void* => byte[]
%template(SerialPortInfoVector) std::vector<itas109::SerialPortInfo>;
// enable inherit CSerialPortListener interface to receive data
%feature("director") itas109::CSerialPortListener;
%include "CSerialPort/SerialPort_global.h"
%include "CSerialPort/SerialPort.h"
%include "CSerialPort/SerialPortListener.h"
%include "CSerialPort/SerialPortInfo.h"

View File

@ -0,0 +1,38 @@
#***************************************************************************
# @file CMakeLists.txt
# @author itas109 (itas109@qq.com) \n\n
# Blog : https://blog.csdn.net/itas109 \n
# Github : https://github.com/itas109 \n
# Gitee : https://gitee.com/itas109 \n
# QQ Group : 129518033
# @brief Lightweight cross-platform serial port library based on C++
# @copyright The CSerialPort is Copyright (C) 2014 itas109 <itas109@qq.com>.
# You may use, copy, modify, and distribute the CSerialPort, under the terms
# of the LICENSE file.
############################################################################
cmake_minimum_required(VERSION 3.8.2)
project(CommCSharp LANGUAGES CSharp)
set(ALL_SRCS
${CMAKE_SWIG_OUTDIR}/cserialportCSharp.cs
${CMAKE_SWIG_OUTDIR}/cserialportCSharpPINVOKE.cs
${CMAKE_SWIG_OUTDIR}/CSerialPort.cs
${CMAKE_SWIG_OUTDIR}/CSerialPortInfo.cs
${CMAKE_SWIG_OUTDIR}/CSerialPortListener.cs
${CMAKE_SWIG_OUTDIR}/BaudRate.cs
${CMAKE_SWIG_OUTDIR}/DataBits.cs
${CMAKE_SWIG_OUTDIR}/FlowControl.cs
${CMAKE_SWIG_OUTDIR}/OperateMode.cs
${CMAKE_SWIG_OUTDIR}/Parity.cs
${CMAKE_SWIG_OUTDIR}/StopBits.cs
${CMAKE_SWIG_OUTDIR}/SerialPortError.cs
${CMAKE_SWIG_OUTDIR}/SerialPortInfo.cs
${CMAKE_SWIG_OUTDIR}/SerialPortInfoVector.cs
)
foreach(src ${ALL_SRCS})
set_source_files_properties(${src} PROPERTIES GENERATED TRUE)
endforeach()
add_executable(${PROJECT_NAME} Program.cs ${ALL_SRCS})

View File

@ -0,0 +1,111 @@
/**
* @file Program.cs
* @author itas109 (itas109@qq.com) \n\n
* Blog : https://blog.csdn.net/itas109 \n
* Github : https://github.com/itas109 \n
* Gitee : https://gitee.com/itas109 \n
* QQ Group : 129518033
* @brief CSharp CSerialPort Example C#CSerialPort示例程序
*/
using System;
using itas109;
public class Program
{
static void Main()
{
CSerialPort sp = new CSerialPort();
Console.WriteLine("Version: {0}\n", sp.getVersion());
CSerialPortListener listener = new MyListener(sp);
SerialPortInfoVector spInfoVec = new SerialPortInfoVector();
spInfoVec = CSerialPortInfo.availablePortInfos();
Console.WriteLine("Available Friendly Ports:");
for (int i = 1; i <= spInfoVec.Count; ++i)
{
Console.WriteLine("{0} - {1} {2}", i, spInfoVec[i - 1].portName, spInfoVec[i - 1].description);
}
if (spInfoVec.Count == 0)
{
Console.WriteLine("No Valid Port");
}
else
{
int input = -1;
do
{
Console.WriteLine("Please Input The Index Of Port(1 - {0})", spInfoVec.Count);
if (!int.TryParse(Console.ReadLine(), out input))
{
continue;
}
if (input >= 1 && input <= spInfoVec.Count)
{
break;
}
} while (true);
string portName = spInfoVec[input - 1].portName;
Console.WriteLine("Port Name: {0}", portName);
sp.init(portName, // windows:COM1 Linux:/dev/ttyS0
9600, // baudrate
Parity.ParityNone, // parity
DataBits.DataBits8, // data bit
StopBits.StopOne, // stop bit
FlowControl.FlowNone, // flow
4096 // read buffer size
);
sp.setReadIntervalTimeout(0); // read interval timeout
sp.open();
Console.WriteLine("Open {0} {1}", portName, sp.isOpen() ? "Success" : "Failed");
// connect for read
sp.connectReadEvent(listener);
// write hex data
sp.writeData(new byte[] { 0x31, 0x32, 0x33, 0x34, 0x35 }, 5);
// write str data
sp.writeData(System.Text.Encoding.Default.GetBytes("itas109"), 7);
}
for (; ; ) { }
}
}
public class MyListener : CSerialPortListener
{
public MyListener(CSerialPort sp)
: base()
{
m_sp = sp;
}
public override void onReadEvent(string portName, uint readBufferLen)
{
if (readBufferLen > 0)
{
// read
byte[] data = new byte[readBufferLen];
int recLen = m_sp.readAllData(data);
string str = System.Text.Encoding.Default.GetString(data);
Console.WriteLine("{0} - Count: {1}, Length: {2}, Str: {3}, Hex: {4}", portName, ++countRead, recLen, str, BitConverter.ToString(data));
// return receive data
m_sp.writeData(data, recLen);
}
}
CSerialPort m_sp;
int countRead = 0;
}

View File

@ -0,0 +1,91 @@
#***************************************************************************
# @file CMakeLists.txt
# @author itas109 (itas109@qq.com) \n\n
# Blog : https://blog.csdn.net/itas109 \n
# Github : https://github.com/itas109 \n
# Gitee : https://gitee.com/itas109 \n
# QQ Group : 129518033
# @brief Lightweight cross-platform serial port library based on C++
# @copyright The CSerialPort is Copyright (C) 2014 itas109 <itas109@qq.com>.
# You may use, copy, modify, and distribute the CSerialPort, under the terms
# of the LICENSE file.
############################################################################
cmake_minimum_required(VERSION 3.8.2)
project(cserialport)
# set output directory
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
# cserialport files
set(CSerialPortRootPath "${CMAKE_CURRENT_SOURCE_DIR}/../..")
include_directories(${CSerialPortRootPath}/include)
list(APPEND CSerialPortSourceFiles ${CSerialPortRootPath}/src/SerialPort.cpp ${CSerialPortRootPath}/src/SerialPortBase.cpp ${CSerialPortRootPath}/src/SerialPortInfo.cpp ${CSerialPortRootPath}/src/SerialPortInfoBase.cpp)
if (WIN32)
list(APPEND CSerialPortSourceFiles ${CSerialPortRootPath}/src/SerialPortInfoWinBase.cpp ${CSerialPortRootPath}/src/SerialPortWinBase.cpp)
list(APPEND CSerialPortSourceFiles ${CSerialPortRootPath}/lib/version.rc)
elseif (UNIX)
list(APPEND CSerialPortSourceFiles ${CSerialPortRootPath}/src/SerialPortInfoUnixBase.cpp ${CSerialPortRootPath}/src/SerialPortUnixBase.cpp)
endif ()
# find java
find_package(Java REQUIRED)
find_package(JNI REQUIRED)
include(UseJava) # add_jar
include_directories(${JNI_INCLUDE_DIRS}) # jni.h
if (WIN32)
link_libraries(setupapi)
elseif (APPLE)
find_library(IOKIT_LIBRARY IOKit)
find_library(FOUNDATION_LIBRARY Foundation)
link_libraries(${FOUNDATION_LIBRARY} ${IOKIT_LIBRARY})
elseif (UNIX)
link_libraries(pthread)
endif ()
# find swig
find_package(SWIG REQUIRED)
include(${SWIG_USE_FILE})
# swig -outdir option(*.java xxx_wrap.cxx xxx_wrap.h)
set(CMAKE_SWIG_OUTDIR "${CMAKE_CURRENT_SOURCE_DIR}/generate")
# call swig in c++ mode
set_property(SOURCE cserialport.i PROPERTY CPLUSPLUS ON)
# set swig package
set(CMAKE_SWIG_FLAGS -package com.itas109.cserialport)
# swig -java -c++ -outdir generate -I../../include -package com.itas109.cserialport cserialport.i
swig_add_library(${PROJECT_NAME} LANGUAGE java SOURCES cserialport.i ${CSerialPortSourceFiles})
# example
set(EXAMPLE_NAME CommJava)
add_jar(
${EXAMPLE_NAME}
example/CommJava.java
${CMAKE_SWIG_OUTDIR}/cserialportJava.java
${CMAKE_SWIG_OUTDIR}/cserialportJavaJNI.java
${CMAKE_SWIG_OUTDIR}/CSerialPort.java
${CMAKE_SWIG_OUTDIR}/CSerialPortListener.java
${CMAKE_SWIG_OUTDIR}/CSerialPortInfo.java
${CMAKE_SWIG_OUTDIR}/BaudRate.java
${CMAKE_SWIG_OUTDIR}/DataBits.java
${CMAKE_SWIG_OUTDIR}/FlowControl.java
${CMAKE_SWIG_OUTDIR}/OperateMode.java
${CMAKE_SWIG_OUTDIR}/Parity.java
${CMAKE_SWIG_OUTDIR}/StopBits.java
${CMAKE_SWIG_OUTDIR}/SerialPortError.java
${CMAKE_SWIG_OUTDIR}/SerialPortInfo.java
${CMAKE_SWIG_OUTDIR}/SerialPortInfoVector.java
ENTRY_POINT CommJava # CommJava.java main class name
)
add_dependencies( ${EXAMPLE_NAME} ${PROJECT_NAME} )
add_custom_command(
TARGET ${PROJECT_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:${PROJECT_NAME}> ${CMAKE_BINARY_DIR}
COMMENT "copy cserialport library"
VERBATIM
)

View File

@ -0,0 +1,110 @@
# CSerialPort for Java
```
swig: 4.1.1 (2022-11-30)
cmake: 3.8.2
java: 1.8.0
```
## Install swig && cmake
### windows
- swig
```
$ wget https://sourceforge.net/projects/swig/files/swigwin/swigwin-4.1.1/swigwin-4.1.1.zip
```
- cmake
```
$ wget https://github.com/Kitware/CMake/releases/download/v3.26.4/cmake-3.26.4-windows-x86_64.msi
```
### linux
- swig
```
$ wget https://sourceforge.net/projects/swig/files/swig/swig-4.1.1/swig-4.1.1.tar.gz
$ tar zxvf swig-4.1.1.tar.gz
$ cd swig-4.1.1
$ ./configure --without-pcre
$ make
$ sudo make install
$ swig -version
SWIG Version 4.1.1
```
- cmake
```
$ wget https://github.com/Kitware/CMake/releases/download/v3.26.4/cmake-3.26.4-linux-x86_64.sh
$ sudo ./cmake-3.26.4-linux-x86_64.sh --prefix=/usr/local --skip-license
$ cmake --version
cmake version 3.26.4
```
## Build
```
cd java
mkdir bin
cd bin
cmake .. -DSWIG_EXECUTABLE=D:/swigwin-4.1.1/swig.exe
cmake --build .
```
**Notice:**
```
D:/swigwin-4.1.1/swig.exe should replace with your path to swig.exe
```
or (config swig to path)
```
set path=D:/swigwin-4.1.1;%path%
cmake ..
```
## Run
```
cd bin
java -Djava.library.path=. -jar CommJava.jar
```
## Tree
```
bindings/java $tree
.
+--- bin
| +--- CommJava.jar
| +--- cserialport.dll
+--- CMakeLists.txt
+--- cserialport.i
+--- example
| +--- CommJava.java
+--- generate
| +--- BaudRate.java
| +--- CSerialPort.java
| +--- CSerialPortInfo.java
| +--- cserialportJava.java
| +--- cserialportJavaJNI.java
| +--- cserialportJAVA_wrap.cxx
| +--- cserialportJAVA_wrap.h
| +--- CSerialPortListener.java
| +--- DataBits.java
| +--- FlowControl.java
| +--- OperateMode.java
| +--- Parity.java
| +--- SerialPortError.java
| +--- SerialPortInfo.java
| +--- SerialPortInfoVector.java
| +--- StopBits.java
+--- README.md
```

View File

@ -0,0 +1,35 @@
/**
* @file cserialport.i
* @author itas109 (itas109@qq.com) \n\n
* Blog : https://blog.csdn.net/itas109 \n
* Github : https://github.com/itas109 \n
* Gitee : https://gitee.com/itas109 \n
* QQ Group : 129518033
* SWIG: 4.1.0
* @brief Java CSerialPort Interface JavaCSerialPort
*/
%module(directors="1") cserialportJava
#define DLL_EXPORT
%{
#include "CSerialPort/SerialPort_global.h"
#include "CSerialPort/SerialPort.h"
#include "CSerialPort/SerialPortListener.h"
#include "CSerialPort/SerialPortInfo.h"
%}
%include "std_vector.i" // std::vector
%include "various.i" // typemaps for java
%apply char* BYTE {void*} // void* => byte[]
%template(SerialPortInfoVector) std::vector<itas109::SerialPortInfo>;
// enable inherit CSerialPortListener interface to receive data
%feature("director") itas109::CSerialPortListener;
%include "CSerialPort/SerialPort_global.h"
%include "CSerialPort/SerialPort.h"
%include "CSerialPort/SerialPortListener.h"
%include "CSerialPort/SerialPortInfo.h"

View File

@ -0,0 +1,126 @@
/**
* @file CommJava.java
* @author itas109 (itas109@qq.com) \n\n
* Blog : https://blog.csdn.net/itas109 \n
* Github : https://github.com/itas109 \n
* Gitee : https://gitee.com/itas109 \n
* QQ Group : 129518033
* @brief Java CSerialPort Example Java的CSerialPort示例程序
*/
import java.util.Scanner;
import com.itas109.cserialport.*;
public class CommJava {
static {
try {
System.loadLibrary("cserialport");
} catch (UnsatisfiedLinkError e) {
System.err.println("Native code library failed to load\n" + e);
System.exit(1);
}
}
public static void main(String[] args) {
CSerialPort sp = new CSerialPort();
System.out.printf("Version: %s\n", sp.getVersion());
MyListener listener = new MyListener(sp);
SerialPortInfoVector spInfoVec = new SerialPortInfoVector();
spInfoVec = CSerialPortInfo.availablePortInfos();
System.out.println("Available Friendly Ports:");
for (int i = 1; i <= spInfoVec.size(); ++i) {
SerialPortInfo serialPortInfo = spInfoVec.get(i - 1);
System.out.printf("%d - %s %s\n", i, serialPortInfo.getPortName(), serialPortInfo.getDescription());
}
if (spInfoVec.size() == 0) {
System.out.println("No Valid Port");
} else {
int input = -1;
do {
System.out.printf("Please Input The Index Of Port(1 - %d)\n", spInfoVec.size());
Scanner sc = new Scanner(System.in);
input = sc.nextInt();
sc.close();
if (input >= 1 && input <= spInfoVec.size()) {
break;
}
} while (true);
String portName = spInfoVec.get(input - 1).getPortName();
System.out.printf("Port Name: %s\n", portName);
sp.init(portName, // windows:COM1 Linux:/dev/ttyS0
9600, // baudrate
Parity.ParityNone, // parity
DataBits.DataBits8, // data bit
StopBits.StopOne, // stop bit
FlowControl.FlowNone, // flow
4096 // read buffer size
);
sp.setReadIntervalTimeout(0); // read interval timeout
sp.open();
System.out.printf("Open %s %s\n", portName, sp.isOpen() ? "Success" : "Failed");
// connect for read
sp.connectReadEvent(listener);
// write hex data
byte[] hex = new byte[] { 0x31, 0x32, 0x33, 0x34, 0x35 };
sp.writeData(hex, 5);
// write str data
byte[] data = "itas109".getBytes();
sp.writeData(data, 7);
}
for (;;) {
}
}
}
class MyListener extends CSerialPortListener {
public MyListener(CSerialPort sp) {
super();
countRead = 0;
m_sp = sp;
}
public void onReadEvent(String portName, long readBufferLen) {
byte[] data = new byte[(int) readBufferLen];
int recLen = m_sp.readAllData(data);
String str = new String(data);
System.out.printf("%s - Count: %d, Length: %d, Str: %s, Hex: %s\n", portName, ++countRead, recLen, str,
byte2hexStr(data));
// return receive data
m_sp.writeData(data, (int) readBufferLen);
}
public static String byte2hexStr(byte[] bytes) {
StringBuilder sb = new StringBuilder();
String ch;
for (byte b : bytes) {
ch = Integer.toHexString(0xFF & b);
if (ch.length() == 1) {
ch = "0x0" + ch;
} else {
ch = "0x" + ch;
}
sb.append(ch).append(" ");
}
return sb.toString();
}
private CSerialPort m_sp;
private int countRead;
}

View File

@ -0,0 +1,63 @@
#***************************************************************************
# @file CMakeLists.txt
# @author itas109 (itas109@qq.com) \n\n
# Blog : https://blog.csdn.net/itas109 \n
# Github : https://github.com/itas109 \n
# Gitee : https://gitee.com/itas109 \n
# QQ Group : 129518033
# @brief Lightweight cross-platform serial port library based on C++
# @copyright The CSerialPort is Copyright (C) 2014 itas109 <itas109@qq.com>.
# You may use, copy, modify, and distribute the CSerialPort, under the terms
# of the LICENSE file.
############################################################################
cmake_minimum_required(VERSION 3.8.2)
project(cserialport)
# set output directory
# set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
# set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
# set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
# cserialport files
set(CSerialPortRootPath "${CMAKE_CURRENT_SOURCE_DIR}/../..")
include_directories(${CSerialPortRootPath}/include)
list(APPEND CSerialPortSourceFiles ${CSerialPortRootPath}/src/SerialPort.cpp ${CSerialPortRootPath}/src/SerialPortBase.cpp ${CSerialPortRootPath}/src/SerialPortInfo.cpp ${CSerialPortRootPath}/src/SerialPortInfoBase.cpp)
if (WIN32)
list(APPEND CSerialPortSourceFiles ${CSerialPortRootPath}/src/SerialPortInfoWinBase.cpp ${CSerialPortRootPath}/src/SerialPortWinBase.cpp)
list(APPEND CSerialPortSourceFiles ${CSerialPortRootPath}/lib/version.rc)
elseif (UNIX)
list(APPEND CSerialPortSourceFiles ${CSerialPortRootPath}/src/SerialPortInfoUnixBase.cpp ${CSerialPortRootPath}/src/SerialPortUnixBase.cpp)
endif ()
# use cmake-js (npm i -g cmake-js)
include_directories(${CMAKE_JS_INC}) # node.h
if (WIN32)
link_libraries(setupapi)
elseif (APPLE)
find_library(IOKIT_LIBRARY IOKit)
find_library(FOUNDATION_LIBRARY Foundation)
link_libraries(${FOUNDATION_LIBRARY} ${IOKIT_LIBRARY})
elseif (UNIX)
link_libraries(pthread)
endif ()
# find swig
find_package(SWIG REQUIRED)
include(${SWIG_USE_FILE})
# swig -outdir option(*.js xxx_wrap.cxx xxx_wrap.h)
set(CMAKE_SWIG_OUTDIR "${CMAKE_CURRENT_SOURCE_DIR}/generate")
# fix Error Module did not self-register
add_definitions(-DBUILDING_NODE_EXTENSION)
# call swig in c++ mode
set_property(SOURCE cserialport.i PROPERTY CPLUSPLUS ON)
# use node javascript engine
set(CMAKE_SWIG_FLAGS -node)
# swig -javascript -c++ -node -outdir generate -I../../include cserialport.i
swig_add_library(${PROJECT_NAME} LANGUAGE javascript SOURCES cserialport.i ${CSerialPortSourceFiles})
set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "" SUFFIX ".node")
target_link_libraries(${PROJECT_NAME} ${CMAKE_JS_LIB}) # windows node.lib

View File

@ -0,0 +1,28 @@
# CSerialPort for JavaScript
```
swig: 4.1.0
cmake: 3.8.2
nodejs: 12.22.12
```
## Build
```
swig -javascript -c++ -node -outdir generate -I../../include cserialport.i
node-gyp configure build --debug
```
or
```
npm i -g cmake-js
cmake-js build -D
```
## Run
```
node example/index.js
```

View File

@ -0,0 +1,36 @@
{
'targets': [
{
'target_name': 'cserialport',
'include_dirs': ['../../include'],
'sources': [
'../../src/SerialPort.cpp',
'../../src/SerialPortBase.cpp',
'../../src/SerialPortInfo.cpp',
'../../src/SerialPortInfoBase.cpp',
'cserialport_wrap.cxx'],
'conditions': [
['OS=="win"', {
'sources': [
'../../src/SerialPortWinBase.cpp',
'../../src/SerialPortInfoWinBase.cpp',
]
}],
['OS=="linux"', {
'cflags': ['-fexceptions'],
'cflags_cc': ['-fexceptions'],
'sources': [
'../../src/SerialPortUnixBase.cpp',
'../../src/SerialPortInfoUnixBase.cpp'
]
}],
['OS=="mac"', {
'sources': [
'../../src/SerialPortUnixBase.cpp',
'../../src/SerialPortInfoUnixBase.cpp'
]
}]
]
}
]
}

View File

@ -0,0 +1,36 @@
/**
* @file cserialport.i
* @author itas109 (itas109@qq.com) \n\n
* Blog : https://blog.csdn.net/itas109 \n
* Github : https://github.com/itas109 \n
* Gitee : https://gitee.com/itas109 \n
* QQ Group : 129518033
* SWIG: 4.1.0
* @brief JavaScript CSerialPort Interface JavaScriptCSerialPort
*/
%module(directors="1") cserialport
#define DLL_EXPORT
%{
#include "CSerialPort/SerialPort_global.h"
#include "CSerialPort/SerialPort.h"
#include "CSerialPort/SerialPortListener.h"
#include "CSerialPort/SerialPortInfo.h"
%}
%include "std_vector.i" // std::vector
%include "cdata.i" // cdata memmove for void*
%include "cmalloc.i" // malloc free for void*
%malloc(void) // malloc void*
%free(void) // free void*
%template(SerialPortInfoVector) std::vector<itas109::SerialPortInfo>;
// enable inherit CSerialPortListener interface to receive data
%feature("director") itas109::CSerialPortListener;
%include "CSerialPort/SerialPort_global.h"
%include "CSerialPort/SerialPort.h"
%include "CSerialPort/SerialPortListener.h"
%include "CSerialPort/SerialPortInfo.h"

View File

@ -0,0 +1,89 @@
/**
* @file index.js
* @author itas109 (itas109@qq.com) \n\n
* Blog : https://blog.csdn.net/itas109 \n
* Github : https://github.com/itas109 \n
* Gitee : https://gitee.com/itas109 \n
* QQ Group : 129518033
* @brief JavaScript CSerialPort Example JavaScript的CSerialPort示例程序
*/
const util = require('util');
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
let addon;
try {
addon = require("../build/Debug/cserialport.node");
} catch (error) {
addon = require("../build/bin/Release/cserialport.node");
}
let sp = new addon.CSerialPort();
console.log(util.format('Version: %s\n', sp.getVersion()));
let spInfoVec = new addon.SerialPortInfoVector();
spInfoVec = addon.CSerialPortInfo.availablePortInfos();
console.log("availableFriendlyPorts: ");
const spInfoVecSize = spInfoVec.size();
if (0 == spInfoVecSize) {
console.log("No valid port");
}
else {
for (let i = 1; i <= spInfoVecSize; i++) {
console.log(util.format('%d - %s %s', i, spInfoVec.get(i - 1).portName, spInfoVec.get(i - 1).description));
}
rl.question(util.format('Please Input The Index Of Port(1 - %d)\n', spInfoVecSize), (myInput) => {
rl.close();
if (myInput >= 1 && myInput <= spInfoVecSize) {
let portName = spInfoVec.get(myInput - 1).portName;
console.log(util.format('Port Name: %s', portName));
sp.init(portName, // windows:COM1 Linux:/dev/ttyS0
9600, // baudrate
addon.ParityNone, // parity
addon.DataBits8, // data bit
addon.StopOne, // stop bit
addon.FlowNone, // flow
4096 // read buffer size
);
sp.open();
console.log(util.format('Open %s %s', portName, sp.isOpen() ? 'Success' : 'Failed'));
// connect for read
// sp.connectReadEvent(listener)
// write hex data
let hex = addon.malloc_void(5);
addon.memmove(hex, '\x31\x32\x33\x34\x35');
sp.writeData(hex, 5);
// addon.free_void(hex);
// write str data
let data = addon.malloc_void(7);
addon.memmove(data, "itas109");
sp.writeData(data, 7);
// addon.free_void(data);
let readData = addon.malloc_void(4096);
let countRead = 0;
for (; ;) {
let recLen = sp.readAllData(readData);
if (recLen > 0) {
let str = addon.cdata(readData, recLen);
console.log(util.format('Count: %d, Length: %d, Str: %s, Hex: %s', ++countRead, recLen, str, Buffer.from(str, 'utf8').toString('hex')));
// return receive data
sp.writeData(readData, recLen);
}
}
}
});
}
delete spInfoVec;

View File

@ -0,0 +1,58 @@
#***************************************************************************
# @file CMakeLists.txt
# @author itas109 (itas109@qq.com) \n\n
# Blog : https://blog.csdn.net/itas109 \n
# Github : https://github.com/itas109 \n
# Gitee : https://gitee.com/itas109 \n
# QQ Group : 129518033
# @brief Lightweight cross-platform serial port library based on C++
# @copyright The CSerialPort is Copyright (C) 2014 itas109 <itas109@qq.com>.
# You may use, copy, modify, and distribute the CSerialPort, under the terms
# of the LICENSE file.
############################################################################
cmake_minimum_required(VERSION 3.8.2)
project(cserialport)
# set output directory
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
# cserialport files
set(CSerialPortRootPath "${CMAKE_CURRENT_SOURCE_DIR}/../..")
include_directories(${CSerialPortRootPath}/include)
list(APPEND CSerialPortSourceFiles ${CSerialPortRootPath}/src/SerialPort.cpp ${CSerialPortRootPath}/src/SerialPortBase.cpp ${CSerialPortRootPath}/src/SerialPortInfo.cpp ${CSerialPortRootPath}/src/SerialPortInfoBase.cpp)
if (WIN32)
list(APPEND CSerialPortSourceFiles ${CSerialPortRootPath}/src/SerialPortInfoWinBase.cpp ${CSerialPortRootPath}/src/SerialPortWinBase.cpp)
list(APPEND CSerialPortSourceFiles ${CSerialPortRootPath}/lib/version.rc)
elseif (UNIX)
list(APPEND CSerialPortSourceFiles ${CSerialPortRootPath}/src/SerialPortInfoUnixBase.cpp ${CSerialPortRootPath}/src/SerialPortUnixBase.cpp)
endif ()
# find python3
find_package (Python3 COMPONENTS Interpreter Development)
include_directories(${Python3_INCLUDE_DIRS})
link_libraries(${Python3_LIBRARIES})
if (WIN32)
link_libraries(setupapi)
elseif (APPLE)
find_library(IOKIT_LIBRARY IOKit)
find_library(FOUNDATION_LIBRARY Foundation)
link_libraries(${FOUNDATION_LIBRARY} ${IOKIT_LIBRARY})
elseif (UNIX)
link_libraries(pthread)
endif ()
# find swig
find_package(SWIG REQUIRED)
include(${SWIG_USE_FILE})
# swig -outdir option(*.py xxx_wrap.cxx xxx_wrap.h)
set(CMAKE_SWIG_OUTDIR "${CMAKE_CURRENT_SOURCE_DIR}/generate")
# call swig in c++ mode
set_property(SOURCE cserialport.i PROPERTY CPLUSPLUS ON)
# swig -python -c++ -outdir generate -I../../include cserialport.i
swig_add_library(${PROJECT_NAME} LANGUAGE python SOURCES cserialport.i ${CSerialPortSourceFiles})

View File

@ -0,0 +1,25 @@
# CSerialPort for Python
```
swig: 4.1.0
cmake: 3.8.2
python: 3.6.8
```
## Build
```
mkdir bin
cd bin
cmake ..
cmake --build . --config Release
```
## Run
```
cmake -E copy generate/cserialport.py example
cmake -E copy bin/bin/Release/_cserialport.pyd example
python example/main.py
```

View File

@ -0,0 +1,36 @@
/**
* @file cserialport.i
* @author itas109 (itas109@qq.com) \n\n
* Blog : https://blog.csdn.net/itas109 \n
* Github : https://github.com/itas109 \n
* Gitee : https://gitee.com/itas109 \n
* QQ Group : 129518033
* SWIG: 4.1.0
* @brief Python CSerialPort Interface PythonCSerialPort
*/
%module(directors="1") cserialport
#define DLL_EXPORT
%{
#include "CSerialPort/SerialPort_global.h"
#include "CSerialPort/SerialPort.h"
#include "CSerialPort/SerialPortListener.h"
#include "CSerialPort/SerialPortInfo.h"
%}
%include "std_vector.i" // std::vector
%include "cdata.i" // cdata memmove for void*
%include "cmalloc.i" // malloc free for void*
%malloc(void) // malloc void*
%free(void) // free void*
%template(SerialPortInfoVector) std::vector<itas109::SerialPortInfo>;
// enable inherit CSerialPortListener interface to receive data
%feature("director") itas109::CSerialPortListener;
%include "CSerialPort/SerialPort_global.h"
%include "CSerialPort/SerialPort.h"
%include "CSerialPort/SerialPortListener.h"
%include "CSerialPort/SerialPortInfo.h"

View File

@ -0,0 +1,84 @@
#***************************************************************************
# @file main.py
# @author itas109 (itas109@qq.com) \n\n
# Blog : https://blog.csdn.net/itas109 \n
# Github : https://github.com/itas109 \n
# Gitee : https://gitee.com/itas109 \n
# QQ Group : 129518033
# @brief Python CSerialPort Example Python的CSerialPort示例程序
############################################################################
import cserialport
def main():
sp = cserialport.CSerialPort()
print("Version: %s\n" %(sp.getVersion()))
listener = MyListener(sp).__disown__()
spInfoVec = cserialport.CSerialPortInfo.availablePortInfos()
print("Available Friendly Ports:")
for index, spInfo in enumerate(spInfoVec, start=1):
print("%d - %s %s" %(index, spInfo.portName, spInfo.description))
if len(spInfoVec) == 0:
print("No Valid Port")
else:
while True:
print("Please Input The Index Of Port(1 - %d)" %(len(spInfoVec)))
myInput=int(input())
if myInput >= 1 and myInput <= len(spInfoVec):
break
portName=spInfoVec[myInput-1].portName
print("Port Name: %s" %(portName))
sp.init(portName, # windows:COM1 Linux:/dev/ttyS0
9600, # baudrate
cserialport.ParityNone, # parity
cserialport.DataBits8, # data bit
cserialport.StopOne, # stop bit
cserialport.FlowNone, # flow
4096 # read buffer size
)
sp.setReadIntervalTimeout(0); # read interval timeout
sp.open()
print("Open %s %s" %(portName, "Success" if sp.isOpen() else "Failed"))
# connect for read
sp.connectReadEvent(listener)
# write hex data
hex = cserialport.malloc_void(5)
cserialport.memmove(hex, '\x31\x32\x33\x34\x35')
sp.writeData(hex, 5)
cserialport.free_void(hex)
# write str data
data = cserialport.malloc_void(7)
cserialport.memmove(data, "itas109")
sp.writeData(data, 7)
cserialport.free_void(data)
while True:
pass
def byte2hexStr(data):
ch = ['0x%02X' % ord(i) for i in data]
return " ".join(ch)
class MyListener(cserialport.CSerialPortListener):
def __init__(self, sp):
MyListener.countRead=0
MyListener.sp=sp
cserialport.CSerialPortListener.__init__(self)
def onReadEvent(self, portName, readBufferLen):
data = cserialport.malloc_void(readBufferLen)
recLen=MyListener.sp.readData(data,readBufferLen)
str=cserialport.cdata(data, readBufferLen)
MyListener.countRead+=1
print("%s - Count: %d, Length: %d, Str: %s, Hex: %s" %(portName, MyListener.countRead, recLen, str, byte2hexStr(str)))
MyListener.sp.writeData(data, readBufferLen)
cserialport.free_void(data)
if __name__ == '__main__':
main()

View File

@ -0,0 +1,15 @@
#
set(CMAKE_SYSTEM_NAME Linux)
# CPU
set(CMAKE_SYSTEM_PROCESSOR aarch64)
#CC++
set(CMAKE_C_COMPILER /usr/bin/aarch64-linux-gnu-gcc)
set(CMAKE_CXX_COMPILER /usr/bin/aarch64-linux-gnu-g++)
#对FIND_PROGRAM()NEVER,ONLY,BOTH,CMAKE_FIND_ROOT_PATH宿NEVER
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
#
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

View File

@ -0,0 +1,15 @@
#
set(CMAKE_SYSTEM_NAME Linux)
# CPU
set(CMAKE_SYSTEM_PROCESSOR arm)
#CC++
set(CMAKE_C_COMPILER /usr/bin/arm-linux-gnueabi-gcc)
set(CMAKE_CXX_COMPILER /usr/bin/arm-linux-gnueabi-g++)
#对FIND_PROGRAM()NEVER,ONLY,BOTH,CMAKE_FIND_ROOT_PATH宿NEVER
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
#
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

View File

@ -0,0 +1,15 @@
#
set(CMAKE_SYSTEM_NAME Linux)
# CPU
set(CMAKE_SYSTEM_PROCESSOR mips64el)
#CC++
set(CMAKE_C_COMPILER /usr/bin/mips64el-linux-gnuabi64-gcc)
set(CMAKE_CXX_COMPILER /usr/bin/mips64el-linux-gnuabi64-g++)
#对FIND_PROGRAM()NEVER,ONLY,BOTH,CMAKE_FIND_ROOT_PATH宿NEVER
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
#
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

View File

@ -0,0 +1,15 @@
#
set(CMAKE_SYSTEM_NAME Linux)
# CPU
set(CMAKE_SYSTEM_PROCESSOR riscv64)
#CC++
set(CMAKE_C_COMPILER /usr/bin/riscv64-linux-gnu-gcc)
set(CMAKE_CXX_COMPILER /usr/bin/riscv64-linux-gnu-g++)
#对FIND_PROGRAM()NEVER,ONLY,BOTH,CMAKE_FIND_ROOT_PATH宿NEVER
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
#
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

View File

@ -0,0 +1,3 @@
#!/bin/bash
find . -path '*/src/*.cpp' -o -path '*/include/CSerialPort/*.hpp' -o -path '*/include/CSerialPort/*.h' | xargs clang-format -style=file -i

View File

@ -0,0 +1,38 @@
#***************************************************************************
# @file cserialport-config.cmake
# @author itas109 (itas109@qq.com) \n\n
# Blog : https://blog.csdn.net/itas109 \n
# Github : https://github.com/itas109 \n
# Gitee : https://gitee.com/itas109 \n
# QQ Group : 129518033
# @brief Lightweight cross-platform serial port library based on C++
# @copyright The CSerialPort is Copyright (C) 2014 itas109 <itas109@qq.com>.
# You may use, copy, modify, and distribute the CSerialPort, under the terms
# of the LICENSE file.
############################################################################
set(CSerialPort_FOUND FALSE)
if(NOT CSerialPort_INCLUDE_DIR)
find_path(CSerialPort_INCLUDE_DIR NAMES
CSerialPort/SerialPort.h
HINTS ${PC_CSerialPort_INCLUDEDIR} ${PC_CSerialPort_INCLUDE_DIRS}
PATH_SUFFIXES CSerialPort )
mark_as_advanced(CSerialPort_INCLUDE_DIR)
endif()
if(NOT CSerialPort_LIBRARY)
find_library(CSerialPort_LIBRARY NAMES
cserialport
libcserialport
HINTS ${PC_CSerialPort_LIBDIR} ${PC_CSerialPort_LIBRARY_DIRS}
)
mark_as_advanced(CSerialPort_LIBRARY)
endif()
if(CSerialPort_INCLUDE_DIR AND CSerialPort_LIBRARY)
set(CSerialPort_FOUND TRUE)
message(STATUS "FOUND CSerialPort, ${CSerialPort_LIBRARY}")
endif()

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="1">
<builddir>cserialport-cppcheck-build-dir</builddir>
<platform>Unspecified</platform>
<analyze-all-vs-configs>false</analyze-all-vs-configs>
<check-headers>true</check-headers>
<check-unused-templates>false</check-unused-templates>
<max-ctu-depth>10</max-ctu-depth>
<includedir>
<dir name="examples/"/>
<dir name="include/"/>
<dir name="src/"/>
</includedir>
<paths>
<dir name="."/>
</paths>
<exclude>
<path name="test/"/>
<path name="lib/"/>
</exclude>
</project>

View File

@ -0,0 +1 @@
root

View File

@ -0,0 +1,54 @@
#***************************************************************************
# @file CMakeLists.txt
# @author itas109 (itas109@qq.com) \n\n
# Blog : https://blog.csdn.net/itas109 \n
# Github : https://github.com/itas109 \n
# Gitee : https://gitee.com/itas109 \n
# QQ Group : 129518033
# @brief Lightweight cross-platform serial port library based on C++
# @copyright The CSerialPort is Copyright (C) 2014 itas109 <itas109@qq.com>.
# You may use, copy, modify, and distribute the CSerialPort, under the terms
# of the LICENSE file.
############################################################################
cmake_minimum_required(VERSION 2.8.12)
project(doc)
find_package(Doxygen)
if (DOXYGEN_FOUND)
set(DOXYGEN_IN ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in)
set(DOXYGEN_OUT_CN ${CMAKE_CURRENT_BINARY_DIR}/DoxyfileCN)
set(DOXYGEN_OUT_EN ${CMAKE_CURRENT_BINARY_DIR}/DoxyfileEN)
file(STRINGS ${CMAKE_CURRENT_SOURCE_DIR}/../include/CSerialPort/SerialPort_version.h VERSION_CONTENTS REGEX "#define CSERIALPORT_VERSION")
string(REGEX MATCH "#define CSERIALPORT_VERSION \"[^\"]*" CSERIALPORT_VERSION ${VERSION_CONTENTS})
string(REGEX REPLACE "[^\"]+\"" "" CSERIALPORT_VERSION ${CSERIALPORT_VERSION})
set(INPUT ${CMAKE_CURRENT_SOURCE_DIR}/../include/CSerialPort)
set(OUTPUT ${CMAKE_BINARY_DIR}/bin)
set(OUTPUT_LANGUAGE "Chinese")
set(MDFILE ${CMAKE_CURRENT_SOURCE_DIR}/../README_zh_CN.md)
set(CHM_FILE "CSerialPort_doc_cn.chm")
set(CHM_INDEX_ENCODING "GB2312")
configure_file(${DOXYGEN_IN} ${DOXYGEN_OUT_CN} @ONLY)
add_custom_target( doc_cn ALL
COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_OUT_CN}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)
set(OUTPUT_LANGUAGE "English")
set(MDFILE ${CMAKE_CURRENT_SOURCE_DIR}/../README.md)
set(CHM_FILE "CSerialPort_doc_en.chm")
set(CHM_INDEX_ENCODING "")
configure_file(${DOXYGEN_IN} ${DOXYGEN_OUT_EN} @ONLY)
add_custom_target(doc_en ALL
COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_OUT_EN}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)
# doc_cn first
add_dependencies(doc_en doc_cn)
else ()
message(FATAL_ERROR "Doxygen not found")
endif ()

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,67 @@
# Frequently Asked Questions
Q1 : CSerialPort可以在一个程序中定义多个对象吗
A : 可以,定义多个串口对象,并且最好关联不同的响应函数
---
Q2 : 有没有办法保证接收的数据不截断?
A : 没有办法保证数据不截断,但是可以使用通信协议的方式将数据拼成一帧完成数据再处理
---
Q3 : 打开串口后报SetCommState()错误
A : 一般情况下是初始化参数错误,可以先使用默认参数,然后逐步添加参数排查问题
---
Q4 : 如何编译动态库?
A : 工程目录CSerialPort\lib下分别有Linux和Windows的动态库编译方法但是更推荐直接使用cmake生成动态库
---
Q5 : 如何调用动态库?
A :
windows下可以运行CSerialPort\examples\CommDLL的示例
linux下将生成的libcserialport.so文件拷贝到CSerialPort\examples\CommNoGui目录执行下列命令即可
```
g++ CSerialPortDemoNoGui.cpp -o CSerialPortDemoNoGui -I../../src -L. -lcserialport
export LD_LIBRARY_PATH=./
./CSerialPortDemoNoGui
```
Q6 : 为何只发送一个字符,串口没有接收?
A :
默认情况下只有当收到的字符数大于1时才会触发读取信号。
可以调用setMinByteReadNoify函数设置读取触发的最小字符数该设置即时生效。
Q7 : How to send/write Hex Data 如何发送/写入hex十六进制数据
A :
more info https://github.com/itas109/CSerialPort/issues/38
```
char sendStr[5] = {0};
sendStr[0] = 0x00;
sendStr[1] = 0x11;
sendStr[2] = 0x22;
sendStr[3] = 0x33;
sendStr[4] = 0x44;
m_serialPort.writeData(sendStr,sizeof(sendStr));
```

View File

@ -0,0 +1 @@
document 文档目录

View File

@ -0,0 +1,47 @@
update : 2023-08-20
```
CSerialPort # root
+--- .clang-format # code format 代码规范
├── bindings # 第三方语言接口
│   ├── c # c interface c接口
│   ├── csharp # csharp interface c#接口
│   ├── java # java interface java接口
│   ├── javascript # javascript interface javascript接口
│   └── python # python interface python接口
├── CHANGELOG.md # change log 修改日志
├── cmake # cross compile 交叉编译
├── CMakeLists.txt
├── doc # document 文档
├── examples # example 示例程序
│   ├── CommMFC # CSerialPort MFC Demo MFC程序示例
│   ├── CommNoGui # CSerialPort No Gui Demo 无界面程序示例
│   ├── CommQT # CSerialPort QT Demo QT程序示例
│   ├── CommTui # CSerialPort tui Demo 文本界面程序示例
│   ├── CommWXWidgets # CSerialPort wxwidgets Demo wxwidgets界面程序示例
├── include # headers 头文件
│   └── CSerialPort
│   ├── ibuffer.hpp # lightweight cross-platform buffer library 轻量级跨平台缓冲区类
│   ├── ithread.hpp # lightweight cross-platform thread library 轻量级跨平台线程类
│   ├── itimer.hpp # lightweight cross-platform timer library 轻量级跨平台定时器类
│   ├── iutils.hpp # lightweight cross-platform utils library 轻量级跨平台工具类
│   ├── SerialPortBase.h # CSerialPort Base class 串口基类
│   ├── SerialPort_global.h # Global difine of CSerialPort 串口全局定义
│   ├── SerialPort.h # lightweight cross-platform serial port library 轻量级跨平台串口类库
│   ├── SerialPortInfoBase.h # CSerialPortInfo Base class 串口信息辅助类基类
│   ├── SerialPortInfo.h # CSerialPortInfo class 串口信息辅助类
│   ├── SerialPortInfoUnixBase.h # CSerialPortInfo unix class unix串口信息辅助类基类
│   ├── SerialPortInfoWinBase.h # CSerialPortInfo windows class windows串口信息辅助类基类
│   ├── SerialPortListener.h # CSerialPortListener interface class 串口事件监听接口类
│   ├── SerialPortUnixBase.h # CSerialPort unix Base class unix串口基类
│   ├── SerialPort_version.h # CSerialPort version 版本定义
│   └── SerialPortWinBase.h # CSerialPort Windows Base class windows串口基类
├── lib # lib 库目录
├── LICENSE # LGPL3.0 license
├── pic # picture 图片
├── README.md
├── README_zh_CN.md
├── src # source 源代码
├── test # unit test 单元测试
└── VERSION # version 版本号
```

View File

@ -0,0 +1,210 @@
# 1.引入头文件错误import error
## 错误信息error info
OS : Windows 7 64bit CN
VS : 2013 、 2015 update 3
CSerialPort : 4.0.0.181210 beta
```
1>CST2.obj : error LNK2019: 无法解析的外部符号 "public: virtual __thiscall itas109::CSerialPort::~CSerialPort(void)" (??1CSerialPort@itas109@@UAE@XZ),该符号在函数 "public: virtual void * __thiscall itas109::CSerialPort::`vector deleting destructor'(unsigned int)" (??_ECSerialPort@itas109@@UAEPAXI@Z) 中被引用
1>CST2Dlg.obj : error LNK2001: 无法解析的外部符号 "public: virtual __thiscall itas109::CSerialPort::~CSerialPort(void)" (??1CSerialPort@itas109@@UAE@XZ)
```
## 原因分析analysis
暂无
## 解决方案solution
需要导入全部的文件到工程不能只引用头文件并且将cpp文件的预编译头修改为"不使用预编译头"。
后续会出一个操作视频。
# 2.this->m_mutex-> is nullptr
## 错误信息error info
OS : Windows 7 64bit CN
VS : 2013 、 2015 update 3
CSerialPort : 4.0.0.181210 beta
```
template<class mt_policy>
class lock_block
{
public:
mt_policy *m_mutex;
lock_block(mt_policy *mtx)
: m_mutex(mtx)
{
m_mutex->lock();//error code line
}
~lock_block()
{
m_mutex->unlock();
}
};
```
## 原因分析analysis
1.VS2015 update 3 测试发现在CSerialPort声明为全局变量时sigslot.h类库会引发空指针异常。
目前原因未完全定位
2.VS2013未发现该问题
3.目前测试发现在MFC自动生成的类内定义CSerialPort成员变量正常但是其他类中也会有崩溃问题等待后续分析
## 解决方案solution
在MFC自动生成的类内定义CSerialPort成员变量
# 3.CommQT连续接收数据是程序崩溃
## 错误信息error info
```
QTextLine: Can't set a line width while not layouting.
QTextLayout::createLine: Called without layouting
QTextLayout::endLayout: Called without beginLayout()
```
## 原因分析analysis
## 解决方案solution
# 4.QT的ui控件写数据异常
## 错误信息error info
```
QObject::connect: Cannot queue arguments of type 'QTextBlock'
(Make sure 'QTextBlock' is registered using qRegisterMetaType().)
QObject: Cannot create children for a parent that is in a different thread.
(Parent is QTextDocument(0x966ae0), parent's thread is QThread(0x93a328), current thread is QThread(0x25f5d88)
QObject::connect: Cannot queue arguments of type 'QTextCursor'
(Make sure 'QTextCursor' is registered using qRegisterMetaType().)
```
## 原因分析analysis
不能在不用线程中操作UI
## 解决方案solution
```
// mainwindow.h
class MainWindow : public QMainWindow, public has_slots<>
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void OnReceive();
void OnUpdateReceive(QString str);
signals:
void emitUpdateReceive(QString str);
...
};
```
```
// mainwindow.cpp
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(this,&MainWindow::emitUpdateReceive,this,&MainWindow::OnUpdateReceive,Qt::QueuedConnection);
...
}
void MainWindow::OnReceive()
{
...
emitUpdateReceive(m_str);
...
}
void MainWindow::OnUpdateReceive(QString str)
{
// update ui
}
```
# 5.fatal error C1010预编译头错误
## 错误信息error info
```
fatal error C1010: 在查找预编译头时遇到意外的文件结尾。是否忘记了向源中添加“#include "stdafx.h"”?
fatal error C1010: unexpected end of file while looking for precompiled header. Did you forget to add '#include "stdafx.h"' to your source?
```
## 原因分析analysis
建立工程时默认勾选了`预编译头`选项导致的
## 解决方案solution
关闭相应cpp的预处理头 :
`cpp文件右键属性 -> C/C++ -> 预编译头`
设置`预编译头`选项为`不使用预编译头`
`cpp Properties -> C/C++ -> Precompiled Headers`
set `Precompiled Header` to `Not Using Precompiled Header`
## 6.接收数据缺少
## 错误信息error info
仅测试了windows
A.数据缺少
CSerialPort::CSerialPort()
{
p_serialPortBase = new CSERIALPORTBASE();
p_serialPortBase->setMinByteReadNoify(2);
//p_serialPortBase->setMinByteReadNoify(1);
((CSERIALPORTBASE *)p_serialPortBase)->readReady.connect(this, &CSerialPort::onReadReady);
}
B.数据正常
{
p_serialPortBase = new CSERIALPORTBASE();
//p_serialPortBase->setMinByteReadNoify(2);
p_serialPortBase->setMinByteReadNoify(1);
((CSERIALPORTBASE *)p_serialPortBase)->readReady.connect(this, &CSerialPort::onReadReady);
}
## 原因分析analysis
可能原因:
单个字符每次都触发
但是2个及2个以上字符只有超过最小数才能触发所以数据会少只有等待下次满足条件能触发。
## 解决方案solution
合理的优化:
设置等待超时例如最小数设置为2但是如果两次接收间隔超过50ms则认为已经不会再来数据同样要触发接收。

View File

@ -0,0 +1,24 @@
#***************************************************************************
# @file CMakeLists.txt
# @author itas109 (itas109@qq.com) \n\n
# Blog : https://blog.csdn.net/itas109 \n
# Github : https://github.com/itas109 \n
# Gitee : https://gitee.com/itas109 \n
# QQ Group : 129518033
# @brief Lightweight cross-platform serial port library based on C++
# @copyright The CSerialPort is Copyright (C) 2014 itas109 <itas109@qq.com>.
# You may use, copy, modify, and distribute the CSerialPort, under the terms
# of the LICENSE file.
############################################################################
cmake_minimum_required(VERSION 2.8.12)
# CommNoGui
add_subdirectory(CommNoGui)
if(WIN32)
find_package(MFC)
if (MFC_FOUND)
add_subdirectory(CommMFC)
endif()
endif()

View File

@ -0,0 +1,152 @@
# MFC使用CSerialPort动态库
CommMFCDLL示例代码支持两种方式编译
- cmake方式(可生成vs2008及以上的版本)
- Visual Studio 2008及以上直接调用(vs2008以上版本可通过Visual Studio进行升级)
注意事项:
- x64动态库只能用于x64的程序调用x86同理
- debug的动态库只能用于动态库程序调用release同理
- 动态库和使用的程序一般要使用相同编译器
## 1. 使用cmake生成CSerialPort动态库
```
$ git clone https://github.com/itas109/CSerialPort
$ cd CSerialPort
$ mkdir bin
$ cd bin
$ cmake .. -DCMAKE_INSTALL_PREFIX=install -DCMAKE_BUILD_TYPE=Debug -DBUILD_SHARED_LIBS=ON
$ cmake --build . --config Debug
$ cmake --install . --config Debug
```
CSerialPort安装目录结构
```
D:/CSerialPort/bin $ tree
.
+--- bin
| +--- libcserialport.dll
+--- include
| +--- CSerialPort
| | +--- osplatformutil.h
| | +--- SerialPort.h
| | +--- SerialPortBase.h
| | +--- SerialPortInfo.h
| | +--- SerialPortInfoBase.h
| | +--- SerialPortInfoUnixBase.h
| | +--- SerialPortInfoWinBase.h
| | +--- SerialPortUnixBase.h
| | +--- SerialPortWinBase.h
| | +--- SerialPort_global.h
| | +--- SerialPort_version.h
| | +--- sigslot.h
+--- lib
| +--- cmake
| | +--- CSerialPort
| | | +--- cserialport-config.cmake
| +--- libcserialport.lib
```
## 2. MFC中以cmake方式使用CSerialPort的动态库【推荐】
### 2.1 通过find_package自动搜索CSerialPort头文件及动态库【推荐】
```
cd D:/CSerialPort/examples/CommMFCDLL
mkdir bin
cd bin
cmake .. -DCMAKE_PREFIX_PATH="../../bin/install"
cmake --build . --config Debug
```
注意:
出现如下错误可设置CMAKE_PREFIX_PATH指定搜索路径如`cmake .. -DCMAKE_PREFIX_PATH="../../bin/install"`
```
Could not find a package configuration file provided by "CSerialPort" with
any of the following names:
CSerialPortConfig.cmake
cserialport-config.cmake
```
### 2.2 手动指定头文件及动态库
注意:可修改`examples\CommMFCDLL\CMakeLists.txt`手动配置路径
CMakeLists.txt
```
cmake_minimum_required(VERSION 2.8.12)
project(CommMFCDLL)
find_package(MFC)
if (NOT MFC_FOUND)
MESSAGE(FATAL_ERROR "MFC not found")
endif()
add_definitions(-D_AFXDLL)
set(CMAKE_MFC_FLAG 2) # 1 the static MFC library 2 shared MFC library
set(MFCFiles CommMFCDLL.cpp CommMFCDLL.h CommMFCDLL.rc CommMFCDLLDlg.cpp CommMFCDLLDlg.h Resource.h stdafx.cpp stdafx.h targetver.h)
if (NOT CSERIALPORT_INSTALL_PATH)
set(CSERIALPORT_INSTALL_PATH CACHE STRING "set CSerialPort Install Path" FORCE)
set_property(CACHE CSERIALPORT_INSTALL_PATH PROPERTY STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/../../bin/install")
endif()
include_directories(${CSERIALPORT_INSTALL_PATH}/include)
link_directories(${CSERIALPORT_INSTALL_PATH}/lib)
add_executable(${PROJECT_NAME} WIN32 ${MFCFiles})
target_link_libraries (${PROJECT_NAME} libcserialport)
```
```
cd D:/CSerialPort/examples/CommMFCDLL
mkdir bin
cd bin
cmake .. -DCSERIALPORT_INSTALL_PATH=../../bin/install
cmake --build . --config Debug
```
## 3. MFC中手动配置方式使用CSerialPort的动态库
### 3.1 添加头文件路径
右键【CommMFCDLL根命名空间】-【属性】-【C/C++】-【常规】-【附加包含目录】-添加CSerialPort的头文件目录
```
D:\CSerialPort\bin\install\include
```
```
$(ProjectDir)\..\..\bin\install\include
```
### 3.2 添加库文件路径
- 添加库文件目录
右键【CommMFC根命名空间】-【属性】-【链接器】-【常规】-【附加库目录】-添加CSerialPort的库文件目录
```
D:\CSerialPort\bin\install\lib
```
```
$(ProjectDir)\..\bin\install\lib
```
- 添加库附加依赖项
右键【CommMFC根命名空间】-【属性】-【链接器】-【输入】-【附加依赖项】-添加`libcserialport.lib`
---
Reference:
1. https://github.com/itas109/CSerialPort
2. https://gitee.com/itas109/CSerialPort
3. https://blog.csdn.net/itas109

View File

@ -0,0 +1,48 @@
#***************************************************************************
# @file CMakeLists.txt
# @author itas109 (itas109@qq.com) \n\n
# Blog : https://blog.csdn.net/itas109 \n
# Github : https://github.com/itas109 \n
# Gitee : https://gitee.com/itas109 \n
# QQ Group : 129518033
# @brief Lightweight cross-platform serial port library based on C++
# @copyright The CSerialPort is Copyright (C) 2014 itas109 <itas109@qq.com>.
# You may use, copy, modify, and distribute the CSerialPort, under the terms
# of the LICENSE file.
############################################################################
cmake_minimum_required(VERSION 2.8.12)
project(CommMFC)
find_package(MFC)
if (NOT MFC_FOUND)
MESSAGE(FATAL_ERROR "MFC not found")
endif()
add_definitions(-D_AFXDLL)
set(CMAKE_MFC_FLAG 2) # 1 the static MFC library 2 shared MFC library
set(CSerialPortRootPath "${CMAKE_CURRENT_SOURCE_DIR}/../../")
include_directories(${CSerialPortRootPath}/include)
list(APPEND CSerialPortSourceFiles ${CSerialPortRootPath}/src/SerialPort.cpp ${CSerialPortRootPath}/src/SerialPortBase.cpp ${CSerialPortRootPath}/src/SerialPortInfo.cpp ${CSerialPortRootPath}/src/SerialPortInfoBase.cpp)
if(WIN32)
list(APPEND CSerialPortSourceFiles ${CSerialPortRootPath}/src/SerialPortInfoWinBase.cpp ${CSerialPortRootPath}/src/SerialPortWinBase.cpp)
elseif(UNIX)
list(APPEND CSerialPortSourceFiles ${CSerialPortRootPath}/src/SerialPortInfoUnixBase.cpp ${CSerialPortRootPath}/src/SerialPortUnixBase.cpp)
endif()
set(MFCFiles CommMFC.cpp CommMFC.h CommMFC.rc CommMFCDlg.cpp CommMFCDlg.h Resource.h stdafx.cpp stdafx.h targetver.h)
add_executable(${PROJECT_NAME} WIN32 ${MFCFiles} ${CSerialPortSourceFiles})
if (WIN32)
# for function availableFriendlyPorts
target_link_libraries( ${PROJECT_NAME} setupapi)
elseif(APPLE)
find_library(IOKIT_LIBRARY IOKit)
find_library(FOUNDATION_LIBRARY Foundation)
target_link_libraries( ${PROJECT_NAME} ${FOUNDATION_LIBRARY} ${IOKIT_LIBRARY})
elseif(UNIX)
target_link_libraries( ${PROJECT_NAME} pthread)
endif ()

View File

@ -0,0 +1,78 @@
// CommMFC.cpp : 定义应用程序的类行为。
//
#include "stdafx.h"
#include "CommMFC.h"
#include "CommMFCDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CCommMFCApp
BEGIN_MESSAGE_MAP(CCommMFCApp, CWinApp)
ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
END_MESSAGE_MAP()
// CCommMFCApp 构造
CCommMFCApp::CCommMFCApp()
{
// TODO: 在此处添加构造代码,
// 将所有重要的初始化放置在 InitInstance 中
}
// 唯一的一个 CCommMFCApp 对象
CCommMFCApp theApp;
// CCommMFCApp 初始化
BOOL CCommMFCApp::InitInstance()
{
// 如果一个运行在 Windows XP 上的应用程序清单指定要
// 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式,
//则需要 InitCommonControlsEx()。否则,将无法创建窗口。
INITCOMMONCONTROLSEX InitCtrls;
InitCtrls.dwSize = sizeof(InitCtrls);
// 将它设置为包括所有要在应用程序中使用的
// 公共控件类。
InitCtrls.dwICC = ICC_WIN95_CLASSES;
InitCommonControlsEx(&InitCtrls);
CWinApp::InitInstance();
AfxEnableControlContainer();
// 标准初始化
// 如果未使用这些功能并希望减小
// 最终可执行文件的大小,则应移除下列
// 不需要的特定初始化例程
// 更改用于存储设置的注册表项
// TODO: 应适当修改该字符串,
// 例如修改为公司或组织名
SetRegistryKey(_T("应用程序向导生成的本地应用程序"));
CCommMFCDlg dlg;
m_pMainWnd = &dlg;
INT_PTR nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
// TODO: 在此放置处理何时用
// “确定”来关闭对话框的代码
}
else if (nResponse == IDCANCEL)
{
// TODO: 在此放置处理何时用
// “取消”来关闭对话框的代码
}
// 由于对话框已关闭,所以将返回 FALSE 以便退出应用程序,
// 而不是启动应用程序的消息泵。
return FALSE;
}

View File

@ -0,0 +1,31 @@
// CommMFC.h : PROJECT_NAME 应用程序的主头文件
//
#pragma once
#ifndef __AFXWIN_H__
#error "在包含此文件之前包含“stdafx.h”以生成 PCH 文件"
#endif
#include "resource.h" // 主符号
// CCommMFCApp:
// 有关此类的实现,请参阅 CommMFC.cpp
//
class CCommMFCApp : public CWinApp
{
public:
CCommMFCApp();
// 重写
public:
virtual BOOL InitInstance();
// 实现
DECLARE_MESSAGE_MAP()
};
extern CCommMFCApp theApp;

View File

@ -0,0 +1,237 @@
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#ifndef APSTUDIO_INVOKED
#include "targetver.h"
#endif
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// Chinese (P.R.C.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
#pragma code_page(936)
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#ifndef APSTUDIO_INVOKED\r\n"
"#include ""targetver.h""\r\n"
"#endif\r\n"
"#include ""afxres.h""\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"#define _AFX_NO_SPLITTER_RESOURCES\r\n"
"#define _AFX_NO_OLE_RESOURCES\r\n"
"#define _AFX_NO_TRACKER_RESOURCES\r\n"
"#define _AFX_NO_PROPERTY_RESOURCES\r\n"
"\r\n"
"#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)\r\n"
"LANGUAGE 4, 2\r\n"
"#pragma code_page(936)\r\n"
"#include ""res\\CommMFC.rc2"" // 非 Microsoft Visual C++ 编辑的资源\r\n"
"#include ""l.CHS\\afxres.rc"" // 标准组件\r\n"
"#endif\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDR_MAINFRAME ICON "res\\CommMFC.ico"
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_ABOUTBOX DIALOGEX 0, 0, 170, 62
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "关于 CommMFC"
FONT 9, "MS Shell Dlg", 0, 0, 0x1
BEGIN
ICON IDR_MAINFRAME,IDC_STATIC,14,14,21,20
LTEXT "CommMFC1.0 版",IDC_STATIC,42,14,114,8,SS_NOPREFIX
LTEXT "Copyright (C) 2021 itas109",IDC_STATIC,42,26,114,8
DEFPUSHBUTTON "确定",IDOK,113,41,50,14,WS_GROUP
END
IDD_COMMMFC_DIALOG DIALOGEX 0, 0, 275, 197
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_APPWINDOW
CAPTION "CommMFC"
FONT 9, "MS Shell Dlg", 0, 0, 0x1
BEGIN
PUSHBUTTON "打开串口",IDC_BUTTON_OPEN_CLOSE,74,99,36,14
COMBOBOX IDC_COMBO_PORT_Nr,55,20,48,49,CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | WS_TABSTOP
LTEXT "串口号",IDC_STATIC,16,22,34,8
COMBOBOX IDC_COMBO_BAUDRATE,55,37,48,49,CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | WS_TABSTOP
LTEXT "波特率",IDC_STATIC,16,39,34,8
EDITTEXT IDC_ReceiveEdit,121,35,138,57,ES_AUTOHSCROLL
EDITTEXT IDC_SendEdit,122,117,137,43,ES_AUTOHSCROLL
GROUPBOX "接收区",IDC_STATIC,117,24,148,76
GROUPBOX "发送区",IDC_STATIC,116,104,151,57
GROUPBOX "串口设置",IDC_STATIC,8,7,104,109
PUSHBUTTON "发送",IDC_BUTTON_SEND,11,151,93,30
LTEXT "Author: itas109\nhttps://github.com/itas109\nhttp://blog.csdn.net/itas109",IDC_STATIC,11,119,98,26
LTEXT "RX : ",IDC_STATIC_RECV_COUNT,114,171,16,8
LTEXT "",IDC_STATIC_RECV_COUNT_VALUE,136,171,44,8
LTEXT "TX : ",IDC_STATIC_SEND_COUNT,184,171,16,8
LTEXT "",IDC_STATIC_SEND_COUNT_VALUE,203,171,44,8
PUSHBUTTON "CL",IDC_BUTTON_CLEAR,250,169,16,13
COMBOBOX IDC_COMBO_PARITY,55,53,48,49,CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | WS_TABSTOP
LTEXT "校验位",IDC_STATIC,16,55,34,8
COMBOBOX IDC_COMBO_STOP,55,84,48,49,CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | WS_TABSTOP
LTEXT "停止位",IDC_STATIC,16,86,34,8
COMBOBOX IDC_COMBO_DATABITS,55,68,48,49,CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | WS_TABSTOP
LTEXT "数据位",IDC_STATIC,16,70,33,8
EDITTEXT IDC_EDIT_RECEIVE_TIMEOUT_MS,190,10,40,14,ES_AUTOHSCROLL
LTEXT "接收超时(ms): ",IDC_STATIC_RECEVICE_TIMEOUT_MS,122,12,59,8
CONTROL "DTR",IDC_CHECK_DTR,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,101,27,10
CONTROL "RTS",IDC_CHECK_RTS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,44,101,27,10
END
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,0,1
PRODUCTVERSION 1,0,0,1
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x4L
FILETYPE 0x1L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "080403a8"
BEGIN
VALUE "CompanyName", "itas109, https://github.com/itas109/CSerialPort"
VALUE "FileDescription", "MFC Application with CSerialPort"
VALUE "FileVersion", "1.0.0.1"
VALUE "InternalName", "CommMFC.exe"
VALUE "LegalCopyright", "Copyright (C) 2021 itas109. All Rights Reserved."
VALUE "OriginalFilename", "CommMFC.exe"
VALUE "ProductName", "CommMFC.exe"
VALUE "ProductVersion", "1.0.0.1"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x804, 936
END
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
IDD_ABOUTBOX, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 163
TOPMARGIN, 7
BOTTOMMARGIN, 55
END
IDD_COMMMFC_DIALOG, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 268
TOPMARGIN, 7
BOTTOMMARGIN, 190
END
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// AFX_DIALOG_LAYOUT
//
IDD_COMMMFC_DIALOG AFX_DIALOG_LAYOUT
BEGIN
0
END
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE
BEGIN
IDS_ABOUTBOX "关于 CommMFC(&A)..."
END
#endif // Chinese (P.R.C.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
#define _AFX_NO_SPLITTER_RESOURCES
#define _AFX_NO_OLE_RESOURCES
#define _AFX_NO_TRACKER_RESOURCES
#define _AFX_NO_PROPERTY_RESOURCES
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
LANGUAGE 4, 2
#pragma code_page(936)
#include "res\CommMFC.rc2" // 非 Microsoft Visual C++ 编辑的资源
#include "l.CHS\afxres.rc" // 标准组件
#endif
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View File

@ -0,0 +1,20 @@

Microsoft Visual Studio Solution File, Format Version 10.00
# Visual Studio 2008
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CommMFC", "CommMFC.vcproj", "{9B0DF21E-DBB7-4190-B72D-0AF734D1387E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{9B0DF21E-DBB7-4190-B72D-0AF734D1387E}.Debug|Win32.ActiveCfg = Debug|Win32
{9B0DF21E-DBB7-4190-B72D-0AF734D1387E}.Debug|Win32.Build.0 = Debug|Win32
{9B0DF21E-DBB7-4190-B72D-0AF734D1387E}.Release|Win32.ActiveCfg = Release|Win32
{9B0DF21E-DBB7-4190-B72D-0AF734D1387E}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,350 @@
<?xml version="1.0" encoding="gb2312"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="CommMFC"
ProjectGUID="{9B0DF21E-DBB7-4190-B72D-0AF734D1387E}"
RootNamespace="CommMFC"
Keyword="MFCProj"
TargetFrameworkVersion="196613"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
UseOfMFC="2"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="_DEBUG"
MkTypLibCompatible="false"
ValidateParameters="true"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="&quot;$(ProjectDir)\..\..\include&quot;"
PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="2"
WarningLevel="3"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="2052"
AdditionalIncludeDirectories="$(IntDir)"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="setupapi.lib"
LinkIncremental="2"
GenerateDebugInformation="true"
SubSystem="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
UseOfMFC="2"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="NDEBUG"
MkTypLibCompatible="false"
ValidateParameters="true"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
MinimalRebuild="false"
RuntimeLibrary="2"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="2"
WarningLevel="3"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="2052"
AdditionalIncludeDirectories="$(IntDir)"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="1"
GenerateDebugInformation="true"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\CommMFC.cpp"
>
</File>
<File
RelativePath=".\CommMFCDlg.cpp"
>
</File>
<File
RelativePath=".\stdafx.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath=".\CommMFC.h"
>
</File>
<File
RelativePath=".\CommMFCDlg.h"
>
</File>
<File
RelativePath=".\Resource.h"
>
</File>
<File
RelativePath=".\stdafx.h"
>
</File>
<File
RelativePath=".\targetver.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
<File
RelativePath=".\res\CommMFC.ico"
>
</File>
<File
RelativePath=".\CommMFC.rc"
>
</File>
<File
RelativePath=".\res\CommMFC.rc2"
>
</File>
</Filter>
<Filter
Name="CSerialPort"
>
<File
RelativePath="..\..\src\SerialPort.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="0"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\src\SerialPortBase.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="0"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\src\SerialPortInfo.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="0"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\src\SerialPortInfoBase.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="0"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\src\SerialPortInfoWinBase.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="0"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\src\SerialPortWinBase.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="0"
/>
</FileConfiguration>
</File>
</Filter>
<File
RelativePath=".\ReadMe.txt"
>
</File>
</Files>
<Globals>
<Global
Name="RESOURCE_FILE"
Value="CommMFC.rc"
/>
</Globals>
</VisualStudioProject>

View File

@ -0,0 +1,411 @@
// CommMFCDlg.cpp : 实现文件
//
#include "stdafx.h"
#include "CommMFC.h"
#include "CommMFCDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// 用于应用程序“关于”菜单项的 CAboutDlg 对话框
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// 对话框数据
enum { IDD = IDD_ABOUTBOX };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
// 实现
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()
// CCommMFCDlg 对话框
CCommMFCDlg::CCommMFCDlg(CWnd* pParent /*=NULL*/)
: CDialog(CCommMFCDlg::IDD, pParent)
, m_ReceiveTimeoutMS(0)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CCommMFCDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_COMBO_PORT_Nr, m_PortNr);
DDX_Control(pDX, IDC_COMBO_BAUDRATE, m_BaudRate);
DDX_Control(pDX, IDC_BUTTON_OPEN_CLOSE, m_OpenCloseCtrl);
DDX_Control(pDX, IDC_SendEdit, m_Send);
DDX_Control(pDX, IDC_ReceiveEdit, m_ReceiveCtrl);
DDX_Control(pDX, IDC_STATIC_RECV_COUNT_VALUE, m_recvCountCtrl);
DDX_Control(pDX, IDC_STATIC_SEND_COUNT_VALUE, m_sendCountCtrl);
DDX_Control(pDX, IDC_COMBO_PARITY, m_Parity);
DDX_Control(pDX, IDC_COMBO_STOP, m_Stop);
DDX_Control(pDX, IDC_COMBO_DATABITS, m_DataBits);
DDX_Text(pDX, IDC_EDIT_RECEIVE_TIMEOUT_MS, m_ReceiveTimeoutMS);
DDV_MinMaxUInt(pDX, m_ReceiveTimeoutMS, 0, 999999);
DDX_Control(pDX, IDC_EDIT_RECEIVE_TIMEOUT_MS, m_ReceiveTimeoutMSCtrl);
DDX_Control(pDX, IDC_CHECK_DTR, m_dtrCtrl);
DDX_Control(pDX, IDC_CHECK_RTS, m_rtsCtrl);
}
BEGIN_MESSAGE_MAP(CCommMFCDlg, CDialog)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON_OPEN_CLOSE, &CCommMFCDlg::OnBnClickedButtonOpenClose)
ON_BN_CLICKED(IDC_BUTTON_SEND, &CCommMFCDlg::OnBnClickedButtonSend)
ON_WM_CLOSE()
ON_BN_CLICKED(IDC_BUTTON_CLEAR, &CCommMFCDlg::OnBnClickedButtonClear)
ON_BN_CLICKED(IDC_CHECK_DTR, &CCommMFCDlg::OnBnClickedCheckDtr)
ON_BN_CLICKED(IDC_CHECK_RTS, &CCommMFCDlg::OnBnClickedCheckRts)
END_MESSAGE_MAP()
// CCommMFCDlg 消息处理程序
BOOL CCommMFCDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// 将“关于...”菜单项添加到系统菜单中。
// IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO: 在此添加额外的初始化代码
rx = 0;
tx = 0;
m_recvCountCtrl.SetWindowText(CString("0"));
m_sendCountCtrl.SetWindowText(CString("0"));
// 默认接收超时时间(毫秒)
m_ReceiveTimeoutMSCtrl.SetWindowText(_T("0"));
CString temp;
//添加波特率到下拉列表
int BaudRateArray[] = {300, 600, 1200, 2400, 4800, 9600, 14400, 19200, 38400, 56000, 57600, 115200};
for (int i = 0; i < sizeof(BaudRateArray) / sizeof(int); i++)
{
temp.Format(_T("%d"), BaudRateArray[i]);
m_BaudRate.InsertString(i, temp);
}
temp.Format(_T("%d"), 9600);
m_BaudRate.SetCurSel(m_BaudRate.FindString(0, temp));
//校验位
std::string ParityArray[] = {"None", "Odd", "Even", "Mark", "Space"};
for (int i = 0; i < sizeof(ParityArray) / sizeof(std::string); i++)
{
#ifdef UNICODE
temp.Format(_T("%S"), ParityArray[i].c_str());
#else
temp.Format(_T("%s"), ParityArray[i].c_str());
#endif
m_Parity.InsertString(i, temp);
}
m_Parity.SetCurSel(0);
//数据位
std::string DataBitsArray[] = {"5", "6", "7", "8"};
for (int i = 0; i < sizeof(DataBitsArray) / sizeof(std::string); i++)
{
#ifdef UNICODE
temp.Format(_T("%S"), DataBitsArray[i].c_str());
#else
temp.Format(_T("%s"), DataBitsArray[i].c_str());
#endif
m_DataBits.InsertString(i, temp);
}
m_DataBits.SetCurSel(3);
//停止位
std::string StopArray[] = {"1", "1.5", "2"};
for (int i = 0; i < sizeof(StopArray) / sizeof(std::string); i++)
{
#ifdef UNICODE
temp.Format(_T("%S"), StopArray[i].c_str());
#else
temp.Format(_T("%s"), StopArray[i].c_str());
#endif
m_Stop.InsertString(i, temp);
}
m_Stop.SetCurSel(0);
//获取串口号
std::vector<SerialPortInfo> m_portsList = CSerialPortInfo::availablePortInfos();
TCHAR m_regKeyValue[256];
for (size_t i = 0; i < m_portsList.size(); i++)
{
#ifdef UNICODE
int iLength;
const char * _char = m_portsList[i].portName;
iLength = MultiByteToWideChar(CP_ACP, 0, _char, strlen(_char) + 1, NULL, 0);
MultiByteToWideChar(CP_ACP, 0, _char, strlen(_char) + 1, m_regKeyValue, iLength);
#else
strcpy_s(m_regKeyValue, 256, m_portsList[i].portName);
#endif
m_PortNr.AddString(m_regKeyValue);
}
m_PortNr.SetCurSel(0);
//OnBnClickedButtonOpenClose();
m_Send.SetWindowText(_T("https://blog.csdn.net/itas109"));
m_SerialPort.connectReadEvent(this);
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
void CCommMFCDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// 如果向对话框添加最小化按钮,则需要下面的代码
// 来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
// 这将由框架自动完成。
void CCommMFCDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 用于绘制的设备上下文
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// 使图标在工作区矩形中居中
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// 绘制图标
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CCommMFCDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void CCommMFCDlg::OnBnClickedButtonOpenClose()
{
if (m_SerialPort.isOpen())
{
m_SerialPort.close();
m_OpenCloseCtrl.SetWindowText(_T("打开串口"));///设置按钮文字为"打开串口"
}
///打开串口操作
else if (m_PortNr.GetCount() > 0)///当前列表的内容个数
{
char portName[256] = {0};
int SelBaudRate;
int SelParity;
int SelDataBits;
int SelStop;
UpdateData(true);
CString temp;
m_PortNr.GetWindowText(temp);
#ifdef UNICODE
strcpy_s(portName, 256, CW2A(temp.GetString()));
#else
strcpy_s(portName, 256, temp.GetBuffer());
#endif
m_BaudRate.GetWindowText(temp);
SelBaudRate = _tstoi(temp);
SelParity = m_Parity.GetCurSel();
m_DataBits.GetWindowText(temp);
SelDataBits = _tstoi(temp);
SelStop = m_Stop.GetCurSel();
m_SerialPort.setReadIntervalTimeout(m_ReceiveTimeoutMS);
m_SerialPort.init(portName, SelBaudRate, itas109::Parity(SelParity), itas109::DataBits(SelDataBits), itas109::StopBits(SelStop));
m_SerialPort.open();
if (m_SerialPort.isOpen())
{
m_OpenCloseCtrl.SetWindowText(_T("关闭串口"));
}
else
{
m_OpenCloseCtrl.SetWindowText(_T("打开串口"));
AfxMessageBox(_T("串口已被占用!"));
}
}
else
{
AfxMessageBox(_T("没有发现串口!"));
}
}
void CCommMFCDlg::OnBnClickedButtonSend()
{
GetDlgItem(IDC_SendEdit)->SetFocus();
if (!m_SerialPort.isOpen()) ///没有打开串口
{
AfxMessageBox(_T("请首先打开串口"));
return;
}
CString temp;
m_Send.GetWindowText(temp);
int len = 0;
char* m_str = NULL;
#ifdef UNICODE
// 兼容中文
CStringA strA(temp);
len = strA.GetLength();
m_str = strA.GetBuffer();
#else
len = temp.GetLength();
m_str = temp.GetBuffer(0);
#endif
m_SerialPort.writeData(m_str, len);
tx += len;
CString str2;
str2.Format(_T("%d"), tx);
m_sendCountCtrl.SetWindowText(str2);
}
void CCommMFCDlg::OnClose()
{
m_SerialPort.close();
CDialog::OnClose();
}
void CCommMFCDlg::onReadEvent(const char *portName, unsigned int readBufferLen)
{
if (readBufferLen > 0)
{
char *data = new char[readBufferLen + 1]; // '\0'
if (data)
{
int recLen = m_SerialPort.readData(data, readBufferLen);
if (recLen > 0)
{
data[recLen] = '\0';
CString str1(data);
rx += str1.GetLength();
m_ReceiveCtrl.SetSel(-1, -1);
m_ReceiveCtrl.ReplaceSel(str1);
CString str2;
str2.Format(_T("%d"), rx);
m_recvCountCtrl.SetWindowText(str2);
}
delete[] data;
data = NULL;
}
}
}
void CCommMFCDlg::OnBnClickedButtonClear()
{
rx = 0;
tx = 0;
m_recvCountCtrl.SetWindowText(CString("0"));
m_sendCountCtrl.SetWindowText(CString("0"));
}
void CCommMFCDlg::OnBnClickedCheckDtr()
{
if(BST_CHECKED == m_dtrCtrl.GetCheck())
{
m_SerialPort.setDtr(true);
}
else
{
m_SerialPort.setDtr(false);
}
}
void CCommMFCDlg::OnBnClickedCheckRts()
{
if (BST_CHECKED == m_rtsCtrl.GetCheck())
{
m_SerialPort.setRts(true);
}
else
{
m_SerialPort.setRts(false);
}
}

View File

@ -0,0 +1,71 @@
// CommMFCDlg.h : 头文件
//
#pragma once
#include <string>
//About CSerialPort start
#include "CSerialPort/SerialPort.h"
#include "CSerialPort/SerialPortInfo.h"
using namespace itas109;
//About CSerialPort end
// CCommMFCDlg 对话框
class CCommMFCDlg : public CDialog, public CSerialPortListener // About CSerialPort
{
// 构造
public:
CCommMFCDlg(CWnd* pParent = NULL); // 标准构造函数
// 对话框数据
enum { IDD = IDD_COMMMFC_DIALOG };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
void onReadEvent(const char *portName, unsigned int readBufferLen); // About CSerialPort
// 实现
protected:
HICON m_hIcon;
// 生成的消息映射函数
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
public:
CComboBox m_PortNr;
CComboBox m_BaudRate;
CComboBox m_Parity;
CComboBox m_Stop;
CComboBox m_DataBits;
CButton m_OpenCloseCtrl;
CEdit m_Send;
CEdit m_ReceiveCtrl;
CStatic m_recvCountCtrl;
CStatic m_sendCountCtrl;
CEdit m_ReceiveTimeoutMSCtrl;
UINT m_ReceiveTimeoutMS;
afx_msg void OnClose();
afx_msg void OnBnClickedButtonOpenClose();
afx_msg void OnBnClickedButtonSend();
afx_msg void OnBnClickedButtonClear();
private:
CSerialPort m_SerialPort;//About CSerialPort
int rx;
int tx;
public:
CButton m_dtrCtrl;
CButton m_rtsCtrl;
afx_msg void OnBnClickedCheckDtr();
afx_msg void OnBnClickedCheckRts();
};

View File

@ -0,0 +1,70 @@
================================================================================
MICROSOFT 基础类库: CommMFC 项目概述
===============================================================================
应用程序向导已为您创建了这个 CommMFC 应用程序。此应用程序不仅演示 Microsoft 基础类的基本使用方法,还可作为您编写应用程序的起点。
本文件概要介绍组成 CommMFC 应用程序的每个文件的内容。
CommMFC.vcproj
这是使用应用程序向导生成的 VC++ 项目的主项目文件。
它包含生成该文件的 Visual C++ 的版本信息,以及有关使用应用程序向导选择的平台、配置和项目功能的信息。
CommMFC.h
这是应用程序的主要头文件。它包括其他项目特定的头文件(包括 Resource.h),并声明 CCommMFCApp 应用程序类。
CommMFC.cpp
这是包含应用程序类 CCommMFCApp 的主要应用程序源文件。
CommMFC.rc
这是程序使用的所有 Microsoft Windows 资源的列表。它包括 RES 子目录中存储的图标、位图和光标。此文件可以直接在 Microsoft Visual C++ 中进行编辑。项目资源位于 2052 中。
res\CommMFC.ico
这是用作应用程序图标的图标文件。此图标包括在主要资源文件 CommMFC.rc 中。
res\CommMFC.rc2
此文件包含不在 Microsoft Visual C++ 中进行编辑的资源。您应该将不可由资源编辑器编辑的所有资源放在此文件中。
/////////////////////////////////////////////////////////////////////////////
应用程序向导创建一个对话框类:
CommMFCDlg.hCommMFCDlg.cpp - 对话框
这些文件包含 CCommMFCDlg 类。该类定义应用程序主对话框的行为。该对话框的模板位于 CommMFC.rc 中,该文件可以在 Microsoft Visual C++ 中进行编辑。
/////////////////////////////////////////////////////////////////////////////
其他功能:
ActiveX 控件
应用程序包括对使用 ActiveX 控件的支持。
/////////////////////////////////////////////////////////////////////////////
其他标准文件:
StdAfx.hStdAfx.cpp
这些文件用于生成名为 CommMFC.pch 的预编译头 (PCH) 文件和名为 StdAfx.obj 的预编译类型文件。
Resource.h
这是标准头文件,它定义新的资源 ID。
Microsoft Visual C++ 读取并更新此文件。
CommMFC.manifest
应用程序清单文件供 Windows XP 用来描述应用程序
对特定版本并行程序集的依赖性。加载程序使用此
信息从程序集缓存加载适当的程序集或
从应用程序加载私有信息。应用程序清单可能为了重新分发而作为
与应用程序可执行文件安装在相同文件夹中的外部 .manifest 文件包括,
也可能以资源的形式包括在该可执行文件中。
/////////////////////////////////////////////////////////////////////////////
其他注释:
应用程序向导使用“TODO:”指示应添加或自定义的源代码部分。
如果应用程序在共享的 DLL 中使用 MFC则需要重新发布这些 MFC DLL如果应用程序所用的语言与操作系统的当前区域设置不同则还需要重新发布对应的本地化资源 MFC90XXX.DLL。有关这两个主题的更多信息请参见 MSDN 文档中有关 Redistributing Visual C++ applications (重新发布 Visual C++ 应用程序)的章节。
/////////////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,40 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by CommMFC.rc
//
#define IDM_ABOUTBOX 0x0010
#define IDD_ABOUTBOX 100
#define IDS_ABOUTBOX 101
#define IDD_COMMMFC_DIALOG 102
#define IDR_MAINFRAME 128
#define IDC_BUTTON_OPEN_CLOSE 1000
#define IDC_COMBO_PORT_Nr 1001
#define IDC_COMBO_BAUDRATE 1002
#define IDC_EDIT1 1003
#define IDC_ReceiveEdit 1003
#define IDC_SendEdit 1004
#define IDC_BUTTON_SEND 1005
#define IDC_BUTTON_TIMER 1006
#define IDC_STATIC_RECV_COUNT 1006
#define IDC_STATIC_RECV_COUNT_VALUE 1007
#define IDC_STATIC_SEND_COUNT 1008
#define IDC_STATIC_SEND_COUNT_VALUE 1009
#define IDC_BUTTON_CLEAR 1010
#define IDC_COMBO_PARITY 1011
#define IDC_COMBO_STOP 1012
#define IDC_COMBO_DATABITS 1013
#define IDC_EDIT_RECEIVE_TIMEOUT_MS 1015
#define IDC_STATIC_RECEVICE_TIMEOUT_MS 1016
#define IDC_CHECK_DTR 1017
#define IDC_CHECK_RTS 1018
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 130
#define _APS_NEXT_COMMAND_VALUE 32771
#define _APS_NEXT_CONTROL_VALUE 1018
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View File

@ -0,0 +1 @@
CSerialPort MFC Demo use source code win32直接调用源码MFC程序示例

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

View File

@ -0,0 +1,13 @@
//
// CommMFC.RC2 - Microsoft Visual C++ 不会直接编辑的资源
//
#ifdef APSTUDIO_INVOKED
#error 此文件不能用 Microsoft Visual C++ 编辑
#endif //APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
// 在此处添加手动编辑的资源...
/////////////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,7 @@
// stdafx.cpp : 只包括标准包含文件的源文件
// CommMFC.pch 将作为预编译头
// stdafx.obj 将包含预编译类型信息
#include "stdafx.h"

View File

@ -0,0 +1,57 @@
// stdafx.h : 标准系统包含文件的包含文件,
// 或是经常使用但不常更改的
// 特定于项目的包含文件
#pragma once
#ifndef _SECURE_ATL
#define _SECURE_ATL 1
#endif
#ifndef VC_EXTRALEAN
#define VC_EXTRALEAN // 从 Windows 头中排除极少使用的资料
#endif
#include "targetver.h"
#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // 某些 CString 构造函数将是显式的
// 关闭 MFC 对某些常见但经常可放心忽略的警告消息的隐藏
#define _AFX_ALL_WARNINGS
#include <afxwin.h> // MFC 核心组件和标准组件
#include <afxext.h> // MFC 扩展
#include <afxdisp.h> // MFC 自动化类
#ifndef _AFX_NO_OLE_SUPPORT
#include <afxdtctl.h> // MFC 对 Internet Explorer 4 公共控件的支持
#endif
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h> // MFC 对 Windows 公共控件的支持
#endif // _AFX_NO_AFXCMN_SUPPORT
#ifdef _UNICODE
#if defined _M_IX86
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
#elif defined _M_IA64
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='ia64' publicKeyToken='6595b64144ccf1df' language='*'\"")
#elif defined _M_X64
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"")
#else
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
#endif
#endif

View File

@ -0,0 +1,26 @@
#pragma once
// 以下宏定义要求的最低平台。要求的最低平台
// 是具有运行应用程序所需功能的 Windows、Internet Explorer 等产品的
// 最早版本。通过在指定版本及更低版本的平台上启用所有可用的功能,宏可以
// 正常工作。
// 如果必须要针对低于以下指定版本的平台,请修改下列定义。
// 有关不同平台对应值的最新信息,请参考 MSDN。
#ifndef WINVER // 指定要求的最低平台是 Windows Vista。
#define WINVER 0x0600 // 将此值更改为相应的值,以适用于 Windows 的其他版本。
#endif
#ifndef _WIN32_WINNT // 指定要求的最低平台是 Windows Vista。
#define _WIN32_WINNT 0x0600 // 将此值更改为相应的值,以适用于 Windows 的其他版本。
#endif
#ifndef _WIN32_WINDOWS // 指定要求的最低平台是 Windows 98。
#define _WIN32_WINDOWS 0x0410 // 将此值更改为适当的值,以适用于 Windows Me 或更高版本。
#endif
#ifndef _WIN32_IE // 指定要求的最低平台是 Internet Explorer 7.0。
#define _WIN32_IE 0x0700 // 将此值更改为相应的值,以适用于 IE 的其他版本。
#endif

Some files were not shown because too many files have changed in this diff Show More