zoukankan      html  css  js  c++  java
  • C++CLI语法 在项目中的使用

    通常情况下,对一个标准的com组件进行集成,网上普遍使用的方式有:

    1、#import *.dll 或 #import *.ocx的方式,VS编译器重新编译后,就会自动生成组件对应的*.tlh文件,该文件类似于头文件,含有com组件中的接口信息,在自己的项目中就可以引用接口或者类了。
    2、#pragma comment(lib, "*.lib")的方式,这种方式可以直接引用lib里的接口声明。

    好巧不巧:项目中碰到的三方组件恰好用这两种方式都不能集成:用第一种方式,VS生成的tlh文件内容是空的;第二种直接引用后,编译报错

    通过三方组件给的C#调用的示例程序,发现该组件的目标运行平台必须选定是X86平台

    自身项目属于C++范畴,所以在查阅部分资料后,遇到了C++/CLI

    #include <Windows.h>
    
    #include <stdio.h>
    
    // 在做类型转换时用到
    using namespace System;
    
    // 组件的路径放在了本地,在实际运行中,将该组件放在了和运行程序的同目录下
    #using "E:C_backup_20180315jzbankCallComSlnCallComDebugInterop.SmartCardLib.dll"
    
    // SmartCardLib是Interop.SmartCardLib.dll内的命名空间
    using namespace SmartCardLib;
    
    // 组件的路径放在了本地,在实际运行中,将该组件放在了和运行程序的同目录下
    #using "E:C_backup_20180315jzbankCallComSlnCallComDebugInterop.IObjectSafetyTLB.dll"
    
    // IObjectSafetyTLB是Interop.IObjectSafetyTLB.dll内的命名空间
    using namespace IObjectSafetyTLB;
    
    // 时间工具
    static SYSTEMTIME t;
    
    void main(){
    
        // clsSmartCardClass是namespace SmartCardLib里的
        // cli语法 注意 ^ 和 gcnew
        clsSmartCardClass ^instance = gcnew clsSmartCardClass();
    
        int ret = -1;
        
        // namespace SmartCardLib里声明的方法
        ret = instance->Connect("param1");
    
        Sleep(3000);
    
        // cli语法 声明变量并初始化
        System::Object^    cardNo = gcnew System::Object();
        System::Object^    customNo1  = gcnew System::Object();
        System::Object^    orderdate1  = gcnew System::Object();
        System::Object^    orderAmount1  = gcnew System::Object();
    
        System::Object^    orderNum1  = gcnew System::Object();
        System::Object^    orderTotal1  = gcnew System::Object();
        System::Object^    fgs1 = gcnew System::Object();
        System::Object^    glz1  = gcnew System::Object();
    
        System::Object^    cardStatus1  = gcnew System::Object();
        System::Object^    cardPwd1  = gcnew System::Object();
        System::Object^    cardType1  = gcnew System::Object();
        System::Object^    chgPwd1 = gcnew System::Object();
    
                                                                    // Int32
        int result = instance->readCard(cardNo, customNo1, orderdate1, orderAmount1,
                                        //
                                         orderNum1, orderTotal1, fgs1, glz1, 
                                        // 
                                         cardStatus1, cardPwd1, cardType1, chgPwd1);
                       
        
        // 文件生成在本地,临时写在特定目录
        FILE *pFile;
        fopen_s( &pFile, "C:\Users\Administrator\teller\device\1\infofile\info.txt", "w+" );
    
        if (result == 0)
        {
            char resv[32] = {0};
            
            
            //////////////////////////////////////////////
            // cli语法 将 System::String^ 转换为 char*
            strcpy(resv, (char*)(void*)System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi((System::String^)cardNo));
            printf("
    ok, instance->readCard()-----------cardNo=%s", resv);
    
            GetLocalTime(&t); 
            fprintf(pFile, "%4d/%02d/%02d %02d:%02d:%02d.%03d %s
    ", 
                t.wYear,t.wMonth,t.wDay,t.wHour,t.wMinute, t.wSecond,t.wMilliseconds, resv);
            fflush(pFile);
    
            memset(resv, 0, sizeof(resv));
    
    
            //////////////////////////////////////////////
            strcpy(resv, (char*)(void*)System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi((System::String^)customNo1));
            printf("
    ok, instance->readCard()-----------customNo1=%s", resv);
    
            GetLocalTime(&t); 
            fprintf(pFile, "%4d/%02d/%02d %02d:%02d:%02d.%03d %s
    ", 
                t.wYear,t.wMonth,t.wDay,t.wHour,t.wMinute, t.wSecond,t.wMilliseconds, resv);
            fflush(pFile);
    
            memset(resv, 0, sizeof(resv));
    
    
            //////////////////////////////////////////////
            strcpy(resv, (char*)(void*)System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi((System::String^)orderdate1));
            printf("
    ok, instance->readCard()-----------orderdate1=%s", resv);
    
            GetLocalTime(&t); 
            fprintf(pFile, "%4d/%02d/%02d %02d:%02d:%02d.%03d %s
    ", 
                t.wYear,t.wMonth,t.wDay,t.wHour,t.wMinute, t.wSecond,t.wMilliseconds, resv);
            fflush(pFile);
    
            memset(resv, 0, sizeof(resv));
    
    
            //////////////////////////////////////////////
            GetLocalTime(&t); 
            fprintf(pFile, "%4d/%02d/%02d %02d:%02d:%02d.%03d %d
    ", 
                t.wYear,t.wMonth,t.wDay,t.wHour,t.wMinute, t.wSecond,t.wMilliseconds, (int)(System::Int32)orderAmount1);
            fflush(pFile);
            printf("
    ok, instance->readCard()-----------orderAmount1=%d", (int)(System::Int32)orderAmount1);
    
    
            //////////////////////////////////////////////
            GetLocalTime(&t); 
            fprintf(pFile, "%4d/%02d/%02d %02d:%02d:%02d.%03d %d
    ", 
                t.wYear,t.wMonth,t.wDay,t.wHour,t.wMinute, t.wSecond,t.wMilliseconds, (int)(System::Int16)orderNum1);
            fflush(pFile);
            printf("
    ok, instance->readCard()-----------orderNum1=%d", (int)(System::Int16)orderNum1);
    
    
            //////////////////////////////////////////////
            GetLocalTime(&t); 
            fprintf(pFile, "%4d/%02d/%02d %02d:%02d:%02d.%03d %d
    ", 
                t.wYear,t.wMonth,t.wDay,t.wHour,t.wMinute, t.wSecond,t.wMilliseconds, (int)(System::Int32)orderTotal1);
            fflush(pFile);
            printf("
    ok, instance->readCard()-----------orderTotal1=%d", (int)(System::Int32)orderTotal1);
    
    
    
            //////////////////////////////////////////////
            strcpy(resv, (char*)(void*)System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi((System::String^)fgs1));
            printf("
    ok, instance->readCard()-----------fgs1=%s", resv);
            
            GetLocalTime(&t); 
            fprintf(pFile, "%4d/%02d/%02d %02d:%02d:%02d.%03d %s
    ", 
                t.wYear,t.wMonth,t.wDay,t.wHour,t.wMinute, t.wSecond,t.wMilliseconds, resv);
            fflush(pFile);
    
            memset(resv, 0, sizeof(resv));
    
    
            //////////////////////////////////////////////
            strcpy(resv, (char*)(void*)System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi((System::String^)glz1));
            printf("
    ok, instance->readCard()-----------glz1=%s", resv);
    
            GetLocalTime(&t); 
            fprintf(pFile, "%4d/%02d/%02d %02d:%02d:%02d.%03d %s
    ", 
                t.wYear,t.wMonth,t.wDay,t.wHour,t.wMinute, t.wSecond,t.wMilliseconds, resv);
            fflush(pFile);
    
            memset(resv, 0, sizeof(resv));
    
    
            //////////////////////////////////////////////
            strcpy(resv, (char*)(void*)System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi((System::String^)cardStatus1));
            printf("
    ok, instance->readCard()-----------cardStatus1=%s", resv);
    
            GetLocalTime(&t); 
            fprintf(pFile, "%4d/%02d/%02d %02d:%02d:%02d.%03d %s
    ", 
                t.wYear,t.wMonth,t.wDay,t.wHour,t.wMinute, t.wSecond,t.wMilliseconds, resv);
            fflush(pFile);
        }
        else
        {
            GetLocalTime(&t); 
            fprintf(pFile, "%4d/%02d/%02d %02d:%02d:%02d.%03d call readCard faild, ret=%d
    ", 
                t.wYear,t.wMonth,t.wDay,t.wHour,t.wMinute, t.wSecond,t.wMilliseconds, result);
        }
    
        fflush(pFile);
        fclose(pFile);
        pFile = NULL;
    
        int dret = instance->Disconnect();
        //printf("
    --, instance->Disconnect()-----------dret=%d", dret);
    
        // 此处延时会导致程序即将结束时报错:Runtime error 217 at 。。。
        //Sleep(3000);
    
        //getchar();
    }

     在C++项目中调用如下:

    #include "LoadDll.h"

    #include <ShlObj.h>

    //用于生成文件夹 mkdir
    #include <direct.h>
    #include <string.h>

    char
    exePath[MAX_PATH] = {0}; ret = checkExePath(exePath, exeName); if(ret < 0) return ret; char params[256] = {0}; sprintf(params, "%s|%d|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s", funcName, timeout, compcode, tmpCardNo, tmpcustomNo, orderdate, orderNum, orderAmount, orderTotal, tmpCardPwd, alertLowLimit, overDraft, idleDays, upLimit ); ret = CallExe(exePath, params, timeout); // 读取生成的文件 char infoFilePath[MAX_PATH] = {0}; ret = checkExePath(infoFilePath, txtName); if(ret < 0) return ret; FILE *pInfoFile = fopen(infoFilePath, "r"); if(NULL == pInfoFile) return -1; char output[8] = {0}; fgets(output, sizeof(output), pInfoFile); fflush(pInfoFile); fclose(pInfoFile); pInfoFile = NULL; // 删除临时生成的文件 //ret = remove(infoFilePath);

    其中CallExe函数实现为:

    int CallExe(char exePath[], const char* params, int timeout)
    {
        SHELLEXECUTEINFO exe = {0};
    
        exe.cbSize = sizeof(SHELLEXECUTEINFO);
        exe.fMask = SEE_MASK_NOCLOSEPROCESS;
        exe.hwnd = NULL;
        exe.lpVerb = NULL;
        exe.lpFile = exePath;
        exe.lpParameters = params;
        exe.lpDirectory = NULL;
        //exe.nShow = SW_NORMAL;
        exe.nShow = SW_HIDE;
        exe.hInstApp = NULL;
    
        BOOL suc = ShellExecuteEx(&exe);
    
        DWORD m = WaitForSingleObject(exe.hProcess, timeout * 1000);
        
        return (int)m;
    
    }

    其中checkExePath函数实现为:

    int checkExePath(char exePath[], char* fileSimpleName)
    {
        char path[MAX_PATH] = {0};
        if (GetDesktopPath(path)){
    
            int desktopPathLenth = strlen((const char *)path);
    
            int i = desktopPathLenth - 1;
            for(; i > 0; i--){
                if(path[i] == '\' || path[i] == '/'){
                    break;
                }
            }
    
            for(int j = 0; j < i; j++){
                exePath[j] = path[j];
            }
    
            sprintf(exePath, "%s%s", exePath, "\fold1");
    
            // 检查“teller”文件夹是否存在
            if (!CheckFolderExist(exePath)){
                _mkdir(exePath);
            }
    
            sprintf(exePath, "%s%s", exePath, "\fold2");
    
            // 检查“device”文件夹是否存在
            if (!CheckFolderExist(exePath)){
                _mkdir(exePath);
            }
    
            sprintf(exePath, "%s%s", exePath, "\fold3");
    
            // 检查“CNG_READER_JZBANK”文件夹是否存在
            if (!CheckFolderExist(exePath)){
                _mkdir(exePath);
            }
    
            // 用户目录/fold1/fold2/fold3/fileSimpleName
            sprintf(exePath, "%s\%s", exePath, fileSimpleName);
            // 检查exe是否存在
    
    
            return 0;
        }
    
        return -1;
    }

    GetDesktopPath的函数实现为:

    //获取桌面目录的绝对路径
    bool GetDesktopPath(char* desktopPath)
    {    
        if (SHGetSpecialFolderPath(NULL, desktopPath, CSIDL_DESKTOP, 0)){
            return TRUE;
        }
    
        return FALSE;
    }

    CheckFolderExist的函数实现为:

    //目录是否存在的检查:
    bool  CheckFolderExist(const char* strPath)
    {
        WIN32_FIND_DATA  wfd;
        bool rValue = FALSE;
        HANDLE hFind = FindFirstFile(strPath, &wfd);
        if ((hFind != INVALID_HANDLE_VALUE) && (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)){
            rValue = TRUE;   
        }
        FindClose(hFind);
        return rValue;
    }
  • 相关阅读:
    telnet模拟http訪问
    network: Android 网络推断(wifi、3G与其它)
    Cocos2d-x学习笔记(19)(TestCpp源代码分析-3)
    Thinkphp编辑器扩展类kindeditor用法
    逛自己的微博,回想以前的那个“我”
    微信生成二维码
    [C++]四种方式求解最大子序列求和问题
    Android 颜色渲染(二) 颜色区域划分原理与实现思路
    Android 颜色渲染(一) 颜色选择器 ColorPickerDialog剖析
    Android 图标上面添加提醒(二)使用开源UI类库 Viewbadger
  • 原文地址:https://www.cnblogs.com/cnblogszs/p/8666614.html
Copyright © 2011-2022 走看看