C++ dll 多重调用封装及C#调用

来源:互联网 发布:如何利用知乎赚钱 编辑:程序博客网 时间:2024/06/05 23:42

1.新建DLL

1.1 新建项目

新建--项目--Visual C++ -- Win32--Win32控制台应用

设定名称为camerStart,解决方案名称可保持默认camerStart,或修改为其他;

在下述向导中选择DLL


选择完成。

1.2 添加文件

1.2.1 添加微图相机启动文件

新建camerStart.h

#pragma once#include <iostream>#include "VTGE_Camera.h"#include <opencv2\opencv.hpp>#include <stdio.h>#include "time.h"#include <fstream>using namespace std;extern "C" _declspec(dllexport) int camerStart(void);//注意此句

同时将微图相机依赖文件都添加在此工程中,即将Camera文件夹放在camerStart\camerStart\下即可;

Camera/Include----GigE_VTAPI.h,VTGE_DataType.h

Camera/Lib------VTGE.dll,VTGE.lib

在项目中添加依赖库和依赖目录的方法,可参考【1】

即:

"

1. 添加编译所需要(依赖)的 lib 文件
    [解决方案资源管理器]“项目->属性->配置属性->连接器->输入->附加依赖项”里填写“winsock.lib”,多个 lib 以空格隔开。(等同于“#pragma comment(lib, "winsock.lib") ”语句)
2. 添加库(Libs)文件目录
    方法 1:[解决方案资源管理器]“项目->属性->配置属性->连接器->常规->附加库目录”
    方法 2:[菜单]“工具->选项->项目和解决方案->C++ 目录”,选择对应平台,然后添加所需“库文件”目录
3. 添加包含(include)文件目录
    方法 1:[解决方案资源管理器]“项目->属性->配置属性->C/C++->常规->附加包含目录”
    方法 2:[菜单]“工具->选项->项目和解决方案->C++ 目录”,选择对应平台,然后添加所需“包括文件”目录

"

同时将VTGE_Camera.cpp,VTGE_Camera.h; ConfigFile.cpp,ConfigFile.h;复制至camerStart\camerStart\下,在项目中直接添加,现有如此现有文件;


ps: 若经过上述设置后,仍然出现无法启动此程序,*.dll丢失,有两种方式解决:

1. 设置环境变量: 右击“计算机”->属性->高级设置->环境变量,设置系统变量;如opencv链接可将系统变量改为:opencv的bin文件路径,即
D:\opencv\CmakeBuildVS13\install\x86\vc12\bin
重启之后,设置方有效;

2. 将dll文件复制至system32文件夹下,立刻有效,但太粗糙了;

1.2.2 添加opencv文件

为了让一些没有安装opencv的同事也能够直接使用该工程,所以直接将原编译后的lib,include复制至该项目下;camerStart\

同时右击添加现有项目属性,加载下述属性文件:


<?xml version="1.0" encoding="utf-8"?><Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">  <ImportGroup Label="PropertySheets" />  <PropertyGroup Label="UserMacros" />  <PropertyGroup>    <IncludePath>..\opencv249\install\include;$(IncludePath)</IncludePath>    <LibraryPath Condition="'$(Platform)'=='Win32'">..\opencv249\install\x86\vc12\lib;$(LibraryPath)</LibraryPath>    <ExecutablePath>..\opencv249\bin;$(ExecutablePath)</ExecutablePath>  </PropertyGroup>  <ItemDefinitionGroup>    <Link Condition="'$(Configuration)'=='Debug'">      <AdditionalDependencies>opencv_calib3d249d.lib;opencv_contrib249d.lib;opencv_core249d.lib;opencv_features2d249d.lib;opencv_flann249d.lib;opencv_gpu249d.lib;opencv_highgui249d.lib;opencv_imgproc249d.lib;opencv_legacy249d.lib;opencv_ml249d.lib;opencv_nonfree249d.lib;opencv_objdetect249d.lib;opencv_ocl249d.lib;opencv_photo249d.lib;opencv_stitching249d.lib;opencv_superres249d.lib;opencv_ts249d.lib;opencv_video249d.lib;opencv_videostab249d.lib;%(AdditionalDependencies)</AdditionalDependencies>    </Link>    <Link Condition="'$(Configuration)'=='Release'">      <AdditionalDependencies>opencv_calib3d249.lib;opencv_contrib249.lib;opencv_core249.lib;opencv_features2d249.lib;opencv_flann249.lib;opencv_gpu249.lib;opencv_highgui249.lib;opencv_imgproc249.lib;opencv_legacy249.lib;opencv_ml249.lib;opencv_nonfree249.lib;opencv_objdetect249.lib;opencv_ocl249.lib;opencv_photo249.lib;opencv_stitching249.lib;opencv_superres249.lib;opencv_ts249.lib;opencv_video249.lib;opencv_videostab249.lib;%(AdditionalDependencies)</AdditionalDependencies>    </Link>  </ItemDefinitionGroup>  <ItemGroup /></Project>



1.3 项目Debug

 1.3.1 VTGE_Camera.cpp文件出现

fatal error C1010: 在查找预编译头时遇到意外的文件结尾。是否忘记了向源中添加“#include "stdafx.h

可参考【2】

即:

1) 在解决方案资源管理器中,右击相应的.cpp文件,点击“属性”
2) 在左侧配置属性中,点开“C/C++”,单击“预编译头”
3) 更改右侧第一行的“创建/使用预编译头”,把选项从“使用预编译头(/Yu)”改成“不使用预编译头”
4) 注:每一个报错的.cpp都要如此更改哦~辛苦一下呗

1.3.2 MFC库error

fatal error C1189: #error : Building MFC application with /MD[d] (CRT dll version) requires MFC shared dll version. Please #define _AFXDLL or do not use /MD[d]  

解决方法,可参考【3】

即:



1.3.3  error LNK2005: _DllMain@12 已经在 dllmain.obj 中定义

有两种解决策略

方法1. 在dllmain.cpp中添加下述代码;参考【4】

// The following symbol used to force inclusion of this module for _USRDLL#ifdef _X86_extern "C" { int _afxForceUSRDLL; }#elseextern "C" { int __afxForceUSRDLL; }#endif

方法2.

项目-》属性-》配置属性-》C/C++/预处理器,去掉预处理器定义中的_USRDLL 即可;参考【5】

1.3.4 无法启动此程序,丢失VTGE.dll

将VTGE.dll复制至windows文件夹下

64位系统
C:\Windows\SysWOW64
32位系统
C:\Windows\System32

并执行regsvr32命令,具体参考【6】


注:

1.在vs下执行生成该项目,在解决方案文件夹下camerStart\Debug下


2.若需要生成Release版本的lib和dll,这需要在上述1.3的debug中的属性设置中选择“配置--所有配置”

否则编译Release时,将出现同样的error;


2. C++直接调用DLL

2.1新建项目

新建--项目--Visual C++ -- Win32--Win32控制台应用,空项目或者取消预编译头

但需要添加至解决方案


从而测试工程即可同DLL在同一个解决方案中;

在解决方案资源管理器中,右击testCamera,选择【设为启动项目】;

2.2 添加opencv属性

同1.2.2类似,在testCamera工程的属性管理器中,右击选择,【添加现有属性表】;

2.3 添加链接库

在testCamera项目中,添加引用库
项目->属性->通用配置


2.3修改testCamera.cpp并运行

,如下

#include "stdafx.h"#include "..\camerStart\camerStart.h"//头文件int main(int argc, _TCHAR* argv[]){camerStart();//camerStart.dll中的APIreturn 0;}

测试ok;

工程文件较大,有1.4G暂不上传,需要瘦身;


3. C#调用C++的DLL

3.1 新建C# Win32控制台项目

3.2 DLL复制

将使用到的DLL及LIB文件copy至bin/下;包括opencv249,Camera,camerStart



3.3修改.cs

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;//for c++ dll 第一步using System.Runtime.InteropServices;namespace CsharpStart{         class Program    {//**********start 2014-09-18 第二步        [DllImport("camerStart.dll", EntryPoint = "openCamer", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)]        private static extern int openCamer();        [DllImport("camerStart.dll", EntryPoint = "getAGVParam", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)]        private static extern int getAGVParam(int directiron, double angle, double offset);//**********end 2014-09-18        static void Main(string[] args)        {            double agv_Angle=0,agv_Offset=0;            int agv_Direction=0;            Console.WriteLine("Hello,World");            openCamer();            getAGVParam(agv_Direction,agv_Angle,agv_Offset);                     Console.WriteLine("directiron=", agv_Direction, "angle=", agv_Angle, "offset=", agv_Offset);        }    }}


需要添加两个地方,如上述代码所示;

同时是否每一个API都需要加入前缀DllImport ???

如此运行即可;


同时根据设计思路:

CVTGE_Camera camera1;<pre name="code" class="csharp">openCamer<span style="font-family: Arial, Helvetica, sans-serif;">();</span>
while(1){
<span style="white-space:pre"></span>getAGVParam(...);<span style="font-family: Arial, Helvetica, sans-serif;">//get image&&Process</span>
}

刚开始时,一直在思考怎样在C#代码中,将类的实例camera1在openCamer()和getAGVParam()间进行传递;

需要变量的转换,而且类CVTGE_很复杂;纠结中。。。

后来灵机一动,将其作为dll中的全局变量是否ok?

然,ok!

解决了类的传递!

3.4  C# 使用C++中的指针

直接上例子,c++的API

int getAGVParam( int* directiron,  double* angle,double* offset);
c#中的使用
   [DllImport("camerStart.dll", EntryPoint = "getAGVParam", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)]        private static extern int getAGVParam(ref int directiron, ref double angle,ref double offset);        static void Main(string[] args)        {            double agv_Angle = 0, agv_Offset = 0;            int agv_Direction = 0;            getAGVParam(ref agv_Direction, ref agv_Angle, ref agv_Offset);            text.WriteLine("directiron={0},angle={1},offset={2}", agv_Direction, agv_Angle, agv_Offset);                    }

ref是关键字;参考【7】


注:

C++调用静态库和动态库的多种方式,请参考【8】

over!

0 0
原创粉丝点击