javascript 调用C++函数
分3步:
一》实现IDispatch 接口
#ifndef _IDISPIMP_H_ #define _IDISPIMP_H_// idispimp.h class CImpIDispatch : public IDispatch { protected:ULONG m_cRef;public:CImpIDispatch(void);~CImpIDispatch(void);STDMETHODIMP QueryInterface(REFIID, void **);STDMETHODIMP_(ULONG) AddRef(void);STDMETHODIMP_(ULONG) Release(void);//IDispatchSTDMETHODIMP GetTypeInfoCount(UINT* pctinfo);STDMETHODIMP GetTypeInfo(/* [in] */ UINT iTInfo,/* [in] */ LCID lcid,/* [out] */ ITypeInfo** ppTInfo);STDMETHODIMP GetIDsOfNames(/* [in] */ REFIID riid,/* [size_is][in] */ LPOLESTR *rgszNames,/* [in] */ UINT cNames,/* [in] */ LCID lcid,/* [size_is][out] */ DISPID *rgDispId);STDMETHODIMP Invoke(/* [in] */ DISPID dispIdMember,/* [in] */ REFIID riid,/* [in] */ LCID lcid,/* [in] */ WORD wFlags,/* [out][in] */ DISPPARAMS *pDispParams,/* [out] */ VARIANT *pVarResult,/* [out] */ EXCEPINFO *pExcepInfo,/* [out] */ UINT *puArgErr);};#endif
#include "StdAfx.h"#include "testDlg.h" // 这个是MFC对话框的头文件,在后面用于调用函数的 #include "Idispimp.h"#include <atlbase.h>#include <mmsystem.h> #include <shlwapi.h>#pragma comment(lib ,"shlwapi.lib")CString javaScriptName="JavaScriptCallCpp"; // javascript 传入的函数名 #define DISPID_CallCppFromJs 1 //与函数名绑定的IDCImpIDispatch::CImpIDispatch( void ) {m_cRef = 0; }CImpIDispatch::~CImpIDispatch( void ) {ASSERT( m_cRef == 0 ); }STDMETHODIMP CImpIDispatch::QueryInterface( REFIID riid, void **ppv ) {*ppv = NULL;if ( IID_IDispatch == riid ){*ppv = this;}if ( NULL != *ppv ){((LPUNKNOWN)*ppv)->AddRef();return NOERROR;}return E_NOINTERFACE; }STDMETHODIMP_(ULONG) CImpIDispatch::AddRef(void) {return ++m_cRef; }STDMETHODIMP_(ULONG) CImpIDispatch::Release(void) {return --m_cRef; }//IDispatch STDMETHODIMP CImpIDispatch::GetTypeInfoCount(UINT* /*pctinfo*/) {return E_NOTIMPL; }STDMETHODIMP CImpIDispatch::GetTypeInfo(/* [in] */ UINT /*iTInfo*/,/* [in] */ LCID /*lcid*/,/* [out] */ ITypeInfo** /*ppTInfo*/) {return E_NOTIMPL; }STDMETHODIMP CImpIDispatch::GetIDsOfNames(/* [in] */ REFIID riid,/* [size_is][in] */ OLECHAR** rgszNames,/* [in] */ UINT cNames,/* [in] */ LCID lcid,/* [size_is][out] */ DISPID* rgDispId) {HRESULT hr;UINT i;// Assume some degree of successhr = NOERROR;for ( i=0; i < cNames; i++) {CString cszName;cszName = rgszNames[i];if (cszName == javaScriptName)//这里判断是否是JS传入的参数名 {rgDispId[i] = DISPID_CallCppFromJs;//将ID绑定,用于Invoke }else {// One or more are unknown so set the return code accordinglyhr = ResultFromScode(DISP_E_UNKNOWNNAME);rgDispId[i] = DISPID_UNKNOWN;}}return hr; }STDMETHODIMP CImpIDispatch::Invoke(/* [in] */ DISPID dispIdMember,/* [in] */ REFIID /*riid*/,/* [in] */ LCID /*lcid*/,/* [in] */ WORD wFlags,/* [out][in] */ DISPPARAMS* pDispParams,/* [out] */ VARIANT* pVarResult,/* [out] */ EXCEPINFO* /*pExcepInfo*/,/* [out] */ UINT* puArgErr) {CtestDlg* pDlg = (CtestDlg*) AfxGetMainWnd();/*参数wFlags有下面若干值----Value DescriptionDISPATCH_METHOD 表示将调用方法。如果属性名称和方法名称相同,则和DISPATCH_PROPERTYGET标志一起设置。DISPATCH_PROPERTYGET 获得属性DISPATCH_PROPERTYPUT 设置属性DISPATCH_PROPERTYPUTREF 通过引用设置属性*/if (dispIdMember == DISPID_CallCppFromJs)// {if (wFlags & DISPATCH_PROPERTYGET)//获取属性 {if (pVarResult != NULL){VariantInit(pVarResult);V_VT(pVarResult)=VT_BOOL;V_BOOL(pVarResult)=true;}}if (wFlags & DISPATCH_METHOD)//这里进行调用 {CString cszArg1;cszArg1 = pDispParams->rgvarg[0].bstrVal;//这里是传入参数 pDlg->TestHtml();// 调用测试的函数 }}return S_OK; }
二》改成COleControlSit
// Custsite.h #ifndef __CUSTOMSITEH__ #define __CUSTOMSITEH__#include "Idispimp.h" #include <afxocc.h> #include <Mshtmhst.h> class CCustomControlSite:public COleControlSite { public:CCustomControlSite(COleControlContainer *pCnt):COleControlSite(pCnt){}BEGIN_INTERFACE_PART(DocHostShowUI, IDocHostShowUI)INIT_INTERFACE_PART(CDocHostSite, DocHostShowUI)STDMETHOD(ShowHelp)(/* [in ] */ HWND hwnd,/* [in ] */ LPOLESTR pszHelpFile,/* [in ] */ UINT uCommand,/* [in ] */ DWORD dwData,/* [in ] */ POINT ptMouse,/* [out] */ IDispatch __RPC_FAR *pDispatchObjectHit);STDMETHOD(ShowMessage)(/* [in ] */ HWND hwnd,/* [in ] */ LPOLESTR lpstrText,/* [in ] */ LPOLESTR lpstrCaption,/* [in ] */ DWORD dwType,/* [in ] */ LPOLESTR lpstrHelpFile,/* [in ] */ DWORD dwHelpContext,/* [out] */ LRESULT __RPC_FAR *plResult);END_INTERFACE_PART(DocHostShowUI)protected:DECLARE_INTERFACE_MAP();BEGIN_INTERFACE_PART(DocHostUIHandler, IDocHostUIHandler)STDMETHOD(ShowContextMenu)(/* [in] */ DWORD dwID,/* [in] */ POINT __RPC_FAR *ppt,/* [in] */ IUnknown __RPC_FAR *pcmdtReserved,/* [in] */ IDispatch __RPC_FAR *pdispReserved);STDMETHOD(GetHostInfo)( /* [out][in] */ DOCHOSTUIINFO __RPC_FAR *pInfo);STDMETHOD(ShowUI)( /* [in] */ DWORD dwID,/* [in] */ IOleInPlaceActiveObject __RPC_FAR *pActiveObject,/* [in] */ IOleCommandTarget __RPC_FAR *pCommandTarget,/* [in] */ IOleInPlaceFrame __RPC_FAR *pFrame,/* [in] */ IOleInPlaceUIWindow __RPC_FAR *pDoc);STDMETHOD(HideUI)(void);STDMETHOD(UpdateUI)(void);STDMETHOD(EnableModeless)(/* [in] */ BOOL fEnable);STDMETHOD(OnDocWindowActivate)(/* [in] */ BOOL fEnable);STDMETHOD(OnFrameWindowActivate)(/* [in] */ BOOL fEnable);STDMETHOD(ResizeBorder)( /* [in] */ LPCRECT prcBorder,/* [in] */ IOleInPlaceUIWindow __RPC_FAR *pUIWindow,/* [in] */ BOOL fRameWindow);STDMETHOD(TranslateAccelerator)( /* [in] */ LPMSG lpMsg,/* [in] */ const GUID __RPC_FAR *pguidCmdGroup,/* [in] */ DWORD nCmdID);STDMETHOD(GetOptionKeyPath)( /* [out] */ LPOLESTR __RPC_FAR *pchKey,/* [in] */ DWORD dw);STDMETHOD(GetDropTarget)(/* [in] */ IDropTarget __RPC_FAR *pDropTarget,/* [out] */ IDropTarget __RPC_FAR *__RPC_FAR *ppDropTarget);STDMETHOD(GetExternal)( /* [out] */ IDispatch __RPC_FAR *__RPC_FAR *ppDispatch);STDMETHOD(TranslateUrl)( /* [in] */ DWORD dwTranslate,/* [in] */ OLECHAR __RPC_FAR *pchURLIn,/* [out] */ OLECHAR __RPC_FAR *__RPC_FAR *ppchURLOut);STDMETHOD(FilterDataObject)( /* [in] */ IDataObject __RPC_FAR *pDO,/* [out] */ IDataObject __RPC_FAR *__RPC_FAR *ppDORet);END_INTERFACE_PART(DocHostUIHandler) };class CCustomOccManager :public COccManager { public:CCustomOccManager(){}COleControlSite* CreateSite(COleControlContainer* pCtrlCont){CCustomControlSite *pSite = new CCustomControlSite(pCtrlCont);return pSite;} }; #endif
#include "StdAfx.h" #include "Custsite.h" #include "test.h" // 主要用到 theApp (261行) BEGIN_INTERFACE_MAP(CCustomControlSite, COleControlSite)INTERFACE_PART(CCustomControlSite, IID_IDocHostShowUI, DocHostShowUI)INTERFACE_PART(CCustomControlSite, IID_IDocHostUIHandler, DocHostUIHandler) END_INTERFACE_MAP()ULONG CCustomControlSite::XDocHostShowUI::AddRef() {METHOD_PROLOGUE(CCustomControlSite, DocHostShowUI);return pThis->ExternalAddRef(); }ULONG CCustomControlSite::XDocHostShowUI::Release() {METHOD_PROLOGUE(CCustomControlSite, DocHostShowUI);return pThis->ExternalRelease(); }HRESULT CCustomControlSite::XDocHostShowUI::QueryInterface(REFIID riid, void ** ppvObj) {METHOD_PROLOGUE(CCustomControlSite, DocHostShowUI);return pThis->ExternalQueryInterface( &riid, ppvObj ); }HRESULT CCustomControlSite::XDocHostShowUI::ShowHelp(HWND hwnd,LPOLESTR pszHelpFile,UINT nCommand,DWORD dwData,POINT ptMouse,IDispatch * pDispatchObjectHit) {METHOD_PROLOGUE(CCustomControlSite, DocHostShowUI);return S_OK; }HRESULT CCustomControlSite::XDocHostShowUI::ShowMessage(HWND hwnd,LPOLESTR lpstrText,LPOLESTR lpstrCaption,DWORD dwType,LPOLESTR lpstrHelpFile,DWORD dwHelpContext,LRESULT * plResult) {METHOD_PROLOGUE(CCustomControlSite, DocHostShowUI);MessageBox(hwnd, (CString)lpstrText, _T("Cpp & JavaScript"), /*dwType*/MB_ICONWARNING);return S_OK; }ULONG FAR EXPORT CCustomControlSite::XDocHostUIHandler::AddRef() {METHOD_PROLOGUE(CCustomControlSite, DocHostUIHandler)return pThis->ExternalAddRef(); }ULONG FAR EXPORT CCustomControlSite::XDocHostUIHandler::Release() { METHOD_PROLOGUE(CCustomControlSite, DocHostUIHandler)return pThis->ExternalRelease(); }HRESULT FAR EXPORT CCustomControlSite::XDocHostUIHandler::QueryInterface(REFIID riid, void **ppvObj) {METHOD_PROLOGUE(CCustomControlSite, DocHostUIHandler)HRESULT hr = (HRESULT)pThis->ExternalQueryInterface(&riid, ppvObj);return hr; }// * CImpIDocHostUIHandler::GetHostInfo // * // * Purpose: Called at initialization // * HRESULT FAR EXPORT CCustomControlSite::XDocHostUIHandler::GetHostInfo( DOCHOSTUIINFO* pInfo ) {METHOD_PROLOGUE(CCustomControlSite, DocHostUIHandler)pInfo->dwFlags = DOCHOSTUIFLAG_NO3DBORDER;pInfo->dwDoubleClick = DOCHOSTUIDBLCLK_DEFAULT;return S_OK; }// * CImpIDocHostUIHandler::ShowUI // * // * Purpose: Called when MSHTML.DLL shows its UI // * HRESULT FAR EXPORT CCustomControlSite::XDocHostUIHandler::ShowUI(DWORD dwID, IOleInPlaceActiveObject * /*pActiveObject*/,IOleCommandTarget * pCommandTarget,IOleInPlaceFrame * /*pFrame*/,IOleInPlaceUIWindow * /*pDoc*/) {METHOD_PROLOGUE(CCustomControlSite, DocHostUIHandler)// We've already got our own UI in place so just return S_OKreturn S_OK; }// * CImpIDocHostUIHandler::HideUI // * // * Purpose: Called when MSHTML.DLL hides its UI // * HRESULT FAR EXPORT CCustomControlSite::XDocHostUIHandler::HideUI(void) {METHOD_PROLOGUE(CCustomControlSite, DocHostUIHandler)return S_OK; }// * CImpIDocHostUIHandler::UpdateUI // * // * Purpose: Called when MSHTML.DLL updates its UI // * HRESULT FAR EXPORT CCustomControlSite::XDocHostUIHandler::UpdateUI(void) {METHOD_PROLOGUE(CCustomControlSite, DocHostUIHandler)// MFC is pretty good about updating it's UI in it's Idle loop so I don't do anything herereturn S_OK; }// * CImpIDocHostUIHandler::EnableModeless // * // * Purpose: Called from MSHTML.DLL's IOleInPlaceActiveObject::EnableModeless // * HRESULT FAR EXPORT CCustomControlSite::XDocHostUIHandler::EnableModeless(BOOL /*fEnable*/) {METHOD_PROLOGUE(CCustomControlSite, DocHostUIHandler)return E_NOTIMPL; }// * CImpIDocHostUIHandler::OnDocWindowActivate // * // * Purpose: Called from MSHTML.DLL's IOleInPlaceActiveObject::OnDocWindowActivate // * HRESULT FAR EXPORT CCustomControlSite::XDocHostUIHandler::OnDocWindowActivate(BOOL /*fActivate*/) {METHOD_PROLOGUE(CCustomControlSite, DocHostUIHandler)return E_NOTIMPL; }// * CImpIDocHostUIHandler::OnFrameWindowActivate // * // * Purpose: Called from MSHTML.DLL's IOleInPlaceActiveObject::OnFrameWindowActivate // * HRESULT FAR EXPORT CCustomControlSite::XDocHostUIHandler::OnFrameWindowActivate(BOOL /*fActivate*/) {METHOD_PROLOGUE(CCustomControlSite, DocHostUIHandler)return E_NOTIMPL; }// * CImpIDocHostUIHandler::ResizeBorder // * // * Purpose: Called from MSHTML.DLL's IOleInPlaceActiveObject::ResizeBorder // * HRESULT FAR EXPORT CCustomControlSite::XDocHostUIHandler::ResizeBorder(LPCRECT /*prcBorder*/, IOleInPlaceUIWindow* /*pUIWindow*/,BOOL /*fRameWindow*/) {METHOD_PROLOGUE(CCustomControlSite, DocHostUIHandler)return E_NOTIMPL; }// * CImpIDocHostUIHandler::ShowContextMenu // * // * Purpose: Called when MSHTML.DLL would normally display its context menu // * HRESULT FAR EXPORT CCustomControlSite::XDocHostUIHandler::ShowContextMenu(DWORD /*dwID*/, POINT* pptPosition,IUnknown* /*pCommandTarget*/,IDispatch* /*pDispatchObjectHit*/) {METHOD_PROLOGUE(CCustomControlSite, DocHostUIHandler)return E_NOTIMPL;//CMenu menu;//menu.LoadMenu(IDR_CUSTOM_POPUP);//CMenu* pSubMenu = menu.GetSubMenu(0);////Because we passed in theApp.m_pMainWnd all of our////WM_COMMAND handlers for the menu items must be handled////in CCustomBrowserApp. If you want this to be your dialog////you will have to grab a pointer to your dialog class and ////pass the hWnd of it into the last parameter in this call//pSubMenu->TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON, pptPosition->x, pptPosition->y, theApp.m_pMainWnd);return S_OK; // We've shown our own context menu. MSHTML.DLL will no longer try to show its own. }// * CImpIDocHostUIHandler::TranslateAccelerator // * // * Purpose: Called from MSHTML.DLL's TranslateAccelerator routines // * HRESULT FAR EXPORT CCustomControlSite::XDocHostUIHandler::TranslateAccelerator(LPMSG lpMsg,/* [in] */ const GUID __RPC_FAR *pguidCmdGroup,/* [in] */ DWORD nCmdID) {METHOD_PROLOGUE(CCustomControlSite, DocHostUIHandler)//disable F5if(lpMsg->message == WM_KEYDOWN && GetAsyncKeyState(VK_F5) < 0)return S_OK;if(GetKeyState(VK_CONTROL) & 0x8000){//disable ctrl + Oif(lpMsg->message == WM_KEYDOWN && GetAsyncKeyState(0x4F) < 0)return S_OK;//disable ctrl + pif(lpMsg->message == WM_KEYDOWN && GetAsyncKeyState(0x50) < 0)return S_OK;//disable ctrl + Nif(lpMsg->message == WM_KEYDOWN && GetAsyncKeyState(0x4E) < 0)return S_OK;}//disable back spaceif(lpMsg->wParam == VK_BACK)return S_OK;return S_FALSE; }// * CImpIDocHostUIHandler::GetOptionKeyPath // * // * Purpose: Called by MSHTML.DLL to find where the host wishes to store // * its options in the registry // * HRESULT FAR EXPORT CCustomControlSite::XDocHostUIHandler::GetOptionKeyPath(BSTR* pbstrKey, DWORD) {METHOD_PROLOGUE(CCustomControlSite, DocHostUIHandler)return E_NOTIMPL; }STDMETHODIMP CCustomControlSite::XDocHostUIHandler::GetDropTarget( /* [in] */ IDropTarget __RPC_FAR *pDropTarget,/* [out] */ IDropTarget __RPC_FAR *__RPC_FAR *ppDropTarget) {METHOD_PROLOGUE(CCustomControlSite, DocHostUIHandler)return E_NOTIMPL; }STDMETHODIMP CCustomControlSite::XDocHostUIHandler::GetExternal( /* [out] */ IDispatch __RPC_FAR *__RPC_FAR *ppDispatch) {// return the IDispatch we have for extending the object ModelIDispatch* pDisp = (IDispatch*)theApp.m_pDispOM; //这里pDisp->AddRef();*ppDispatch = pDisp;return S_OK; }STDMETHODIMP CCustomControlSite::XDocHostUIHandler::TranslateUrl( /* [in] */ DWORD dwTranslate,/* [in] */ OLECHAR __RPC_FAR *pchURLIn,/* [out] */ OLECHAR __RPC_FAR *__RPC_FAR *ppchURLOut) {METHOD_PROLOGUE(CCustomControlSite, DocHostUIHandler)return E_NOTIMPL; }STDMETHODIMP CCustomControlSite::XDocHostUIHandler::FilterDataObject( /* [in] */ IDataObject __RPC_FAR *pDO,/* [out] */ IDataObject __RPC_FAR *__RPC_FAR *ppDORet) {METHOD_PROLOGUE(CCustomControlSite, DocHostUIHandler)return E_NOTIMPL; }
三》修改App
1.增加头文件 #include "Custsite.h"
2.在 InitInstance()函数中 增加2处,修改一处
新增的两处
CCustomOccManager *pMgr = new CCustomOccManager;m_pDispOM = new CImpIDispatch;
修改的一处
把AfxEnableControlContainer();改为 AfxEnableControlContainer(pMgr);
四》htm文件为:
<!DOCTYPE html> <html> <head><meta charset=gb2312><title></title><script type="text/javascript">function CallCpp(){//JavaScriptCallCpp 是C++中函数,//与idispimp.cpp文件中javaScriptName进行对应并且与DISPID_CallCppFromJs进行绑定window.external.JavaScriptCallCpp('This is a test for call C++ in JavaScript');}</script> </head> <body><button οnclick="CallCpp()">JavaScript访问C++代码</button> </body> </html>
五: 整个完成了
转载于:https://www.cnblogs.com/dengpeng1004/p/5236717.html
javascript 调用C++函数相关推荐
- CEF:JavaScript 调用 C++ 函数 Demo(VS2013)
上一篇 CEF:C++ 调用 JavaScript 函数 Demo(VS2013)讲了外部 C++ 代码如何调用网页内 JavaScript 函数的问题,这一篇换个方向,说一说网页内 JavaScri ...
- JavaScript调用其他函数中的变量
JS中一个函数调用另一个函数中的变量 funcA() {this.location = [];this.location = 100; }, funcB() {cc.log(this.location ...
- Android在使用WebView时,通过Javascript调用JAVA函数
webView = (WebView) findViewById(R.id.article_webview);//WebView启用Javascript脚本执行 webView.getSettings ...
- javascript调用一个函数(对象),new和直接调用的区别
function Man(age){this.sex="male";this.age=age; } m1=Man(20); m2=new Man(21); m1就是函数Man()执 ...
- WebAssembly第三章 JavaScript调用C\C++ 关键字:wasm emcc js c++ c
系列文章目录 第一章 WebAssembly概念 第二章 Emscripten详解 第三章 JavaScript调用C\C++ 第四章 C\C++调用JavaScript WebAssembly第三章 ...
- JavaScript调用Applet的函数
为什么80%的码农都做不了架构师?>>> #需求 通过浏览器操作客户端的文件浏览器,打开网站指定文件夹,并对文件进行读写. #初步调用 ##环境安装 浏览器Firefox与Ja ...
- 深入理解JavaScript系列(4):立即调用的函数表达式
前言 大家学JavaScript的时候,经常遇到自执行匿名函数的代码,今天我们主要就来想想说一下自执行. 在详细了解这个之前,我们来谈了解一下"自执行"这个叫法,本文对这个功能的叫 ...
- C#与Javascript变量、函数之间的相互调用2008年11月28日 星期五 05:28 P.M.1.如何在JavaScript访问C#函数?
C#与Javascript变量.函数之间的相互调用 2008年11月28日 星期五 05:28 P.M. 1.如何在JavaScript访问C#函数? 2.如何在JavaScript访问C#变量? 3 ...
- js调用php函数兵每秒刷新,深入理解JavaScript立即调用函数表达式(IIFE)
立即调用函数 目录一.了解立即调用函数表达式 二.立即调用函数表达式报错了? 三.使用立即调用函数的正确姿势 四.常见使用场景 写在最后 一.了解立即调用函数表达式 1.1 思维导图 1.2 什么是立 ...
最新文章
- 2022-2028年全球与中国氢碘化物市场智研瞻分析报告
- 【iOS】快速集成轮播控件
- 1.7 对新序列采样-深度学习第五课《序列模型》-Stanford吴恩达教授
- 实战并发编程 - 09多线程Guarded Suspension模式案例实战
- Composer The openssl extension is required for SSL/TLS protection
- Swift - UITableView状态切换效果
- Linux 如何加载并口/打印口驱动
- 前端学习(2580):提升开发效率的工具
- word2vec相似度计算_AAAI-2016 | 使用孪生递归网络的句子语义相似度计算方法
- leetcode python3 简单题191. Number of 1 Bits
- Win7中的clr_optimization服务
- 《Algorithms 4th Edition》读书笔记——2.4 优先队列(priority queue)-Ⅵ
- python的基础操作_python列表基础操作
- 管家婆的验证服务器失败,管家婆登陆提示“连接服务器失败”怎么办
- halcon轮廓擦除_【Halcon】轮廓处理
- linux安装frps服务,ubuntu搭建frps服务
- 使用BOMC升级 lenovo Thinksystem 和system x系列服务器微码到最新
- [Usaco2008 Oct]Watering Hole 挖水井
- React-从0到1搭建一个React项目(一)
- 二、读取编码器数值实现电机测速—1 、配置串口通信;
热门文章
- ISA频繁断线的原因和解决方法
- Airbnb如何简化1000多位工程师的Kubernetes工作流程?
- AIX学习之--文件系统修复(/home)
- 论文都看不懂,你还搞什么人工智能?
- RHEL下SendMail修改发邮箱地址
- Swift教程_零基础学习Swift完整实例(八)_swift完整实例(添加View的动画效果、添加View的阴影)...
- bootstrap 栅格系统实现类似table跨行
- 面试题 04.04. 检查平衡性
- c语言 string.h部分常用函数的实现
- 问题 B: 算术基本运算 山东科技大学 oj c语言