CodeV和C++交互CODEV版本2023-03
尝试用CodeV的API手册中的C++示例代码与CodeV进行交互,但是发现API手册的示例代码与提供的库文件不匹配,网上没有找到很详细的解决方案,自己摸索出来一个解决办法仅供参考,过程如下。
codev2023.03 示例代码(无法运行)
The following sample code in C++ sets the starting directory to C:\CVUSER, starts CODE V, restores the dbgauss lens, runs a surface listing, and then closes the CODE V session. Examples for other languages can be found in the \com subfolder (for example, C:\CODEV202303\com).
翻译:下面C++的示例代码设置起始目录为C:\CVUSER,启动CODEV,打开dbgauss镜头,运行并输出表面参数,然后关闭CODEV回话。其他语言的示例可以在com子文件夹中找到
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 #define WINVER 0x0600 #define WIN32_WINNT 0x0600 #define WIN32_IE 0x0700 #define UNICODE #define _UNICODE #include <afxdisp.H> #include <iostream> #import "cvcommand.tlb" raw_interfaces_only named_guids void main () { CoInitialize(nullptr); CVCommandLib::ICVApplication* pCodeV = nullptr; auto sProgid = std ::string ("CodeV.Application" );_bstr_t bstrProgID = CA2W(sProgid.c_str());CLSID nClassId; auto hr = CLSIDFromProgID(bstrProgID, &nClassId);if (FAILED(hr)){ std ::cerr << "No COM object registered\n" ;exit (1 );} hr = CoCreateInstance( nClassId, nullptr, CLSCTX_LOCAL_SERVER, __uuidof(CVCommandLib::ICVApplication), (void **) &pCodeV); if (FAILED(hr)){ std ::cerr << "Unable to create COM instance\n" ;CoUninitialize(); exit (1 );} hr = pCodeV->StartCodeV(); if ( FAILED(hr) ){ std ::cerr << "Unable to start CODE V\n" ;CoUninitialize(); exit (1 );} _bstr_t bstrtCommand = CA2W("len new" ); _bstr_t bstrtResult;hr = pCodeV->Command(bstrtCommand, &bstrtResult.GetBSTR()); if (SUCCEEDED(hr)){ std ::string result = CW2A(bstrtResult);std ::cout << result.data() << std ::endl ;} else { std ::cout << "Command() failed. HRESULT = " << std ::hex << hr << std ::endl ;} hr = pCodeV->StopCodeV(); hr = pCodeV->Release(); CoUninitialize(); }
运行方法:Copy the cvcommand.tlb file from the CODE V installation folder to the working directory for the Visual C++ project. You can then compile the sample file using the CL command as shown below:
cl /I"." /EHsc sample.cpp
#define NTDDI_VERSION NTDDI_VISTA
where the filename is sample.cpp and Visual C++ is installed and in your path.
翻译:将 cvcommand.tlb 文件从 CODE V 安装文件夹复制到 Visual C 项目的工作目录中。然后可以使用如下所示的 CL 命令编译示例文件:
cl /I"." /EHsc sample.cpp
#define NTDDI_VERSION NTDDI_VISTA
其中文件名为 sample.cpp,并且已安装 Visual C++ 并添加到你的路径中。
按照文档运行后出现报错,我分析主要存在两个报错:第一个是#import "cvcommand.tlb" raw_interfaces_only这里引用的库文件和代码不匹配,有可能是因为版本比较老,导致库文件和代码不匹配;第二个是#include <afxdisp.H>这里引用的afxdisp库比较老,导致CA2W等无法使用,这个可以用其他方法代替。
解决方案
下面这个没有问题,按照这个来就行
Copy the cvcommand.tlb file from the CODE V installation folder to the working directory for the Visual C++ project. You can then compile the sample file using the CL command as shown below:
cl /I"." /EHsc sample.cpp
#define NTDDI_VERSION NTDDI_VISTA
where the filename is sample.cpp and Visual C++ is installed and in your path.
代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 #define WINVER 0x0600 #define WIN32_WINNT 0x0600 #define WIN32_IE 0x0700 #define UNICODE #define _UNICODE #include <iostream> #include <string> #include <comdef.h> #include <io.h> #include <fcntl.h> #import "cvcommand.tlb" raw_interfaces_only named_guids void main () { _setmode(_fileno(stdout ), _O_U16TEXT); _setmode(_fileno(stderr ), _O_U16TEXT); CoInitialize(nullptr); CVCommandLib::ICVCommand* pCodeV = nullptr; std ::string sProgid = "CodeV.Application" ; _bstr_t bstrProgID = sProgid.c_str(); CLSID nClassId; auto hr = CLSIDFromProgID(bstrProgID, &nClassId); if (FAILED(hr)) { std ::wcerr << L"No COM object registered\n" ; exit (1 ); } hr = CoCreateInstance( __uuidof(CVCommandLib::CVCommand), nullptr, CLSCTX_LOCAL_SERVER, __uuidof(CVCommandLib::ICVCommand), (void **)&pCodeV); if (FAILED(hr)) { std ::wcerr << L"Unable to create COM instance. HRESULT: 0x" << std ::hex << hr << L"\n" ; CoUninitialize(); exit (1 ); } BSTR bstrStartDir = nullptr; hr = pCodeV->GetStartingDirectory(&bstrStartDir); if (SUCCEEDED(hr) && bstrStartDir != nullptr) { std ::wcout << L"StartDir: " << (wchar_t *)bstrStartDir << std ::endl ; SysFreeString(bstrStartDir); } else { std ::wcerr << L"GetStartingDirectory failed. HRESULT: 0x" << std ::hex << hr << std ::endl ; } hr = pCodeV->StartCodeV(); if (FAILED(hr)) { std ::wcerr << L"Unable to start CODE V\n" ; CoUninitialize(); exit (1 ); } _bstr_t bstrtCommand = "len new" ; _bstr_t bstrtResult; hr = pCodeV->Command(bstrtCommand, &bstrtResult.GetBSTR()); if (SUCCEEDED(hr)) { if (bstrtResult.length() > 0 ) { std ::wstring result = (wchar_t *)bstrtResult; std ::wcout << L"Result: " << result << std ::endl ; } else { std ::wcout << L"Command executed successfully (no output)." << std ::endl ; } } else { std ::wcout << L"Command() failed. HRESULT = " << std ::hex << hr << std ::endl ; } hr = pCodeV->StopCodeV(); hr = pCodeV->Release(); CoUninitialize(); return ; }
上面这个代码解决了两个问题:1、检查编译得到的cvcommand.tlh文件,可以发现并没有ICVApplication这个成员,检查发现ICVCommand这个才是正确的;2、使用comdef.h代替afxdisp.H来对COM字符串进行处理。
经测试可以成功输出