C++与C#对比学习:预编译与编译机制(二)

常用预处理指令

 

C++中常用预处理指令

前面讲了主要有四种1.include引用头文件 2.条件编译#define  #ifdef等  3.#define定义宏  4.progma

 

1.include引用头文件

我们经常会看到#include "ABC.h" 和#include <iostream>这样的写法. "ABC.h"这样带个h的预编译时直接在当前项目目录上去找.而<iostream>这样的是去系统目录中.那你可能会问系统目录在哪里啊? 我找了下也没找着.只在C盘中找到个有啥WinDef.h和Windows.h这些头文件的目录.反正就是装VS时指定的一些啥目录吧.你编译时它VS肯定能找到的.而且那也是些早写好的.h文件,跟你写的头文件没啥不一样.

另外我发现"stdafx.h"这个头文件只能放第一行,如果你把#include <iostream>放它前面去了,实际上就没有引用到iostream.我也不知道这是为啥来着啊

 

2.条件编译

如果你需要装软件整成不同的版本,比如企业版或精简版之类啊.或者要想加入些debug时用到的代码就可以用到条件编译.这是两种最经常用到条件编译的场景.

 

#include "stdafx.h"

#include <iostream>

#define GOD

void main()

{

#ifdef GOD

std::cout<<"my god";

#else

std::cout<<"hell";

#endif

}

上面就是条件编译的简单用法.像if条件一样,你还可以多来几个else if,不过如果用else if的话应该这样写#elif

你假如在这里没用定义GOD,而是在其他头文件中定义了,然后添加头文件引用.那也相当于定义了GOD.还有就是GOD的定义只能定义在所以头文件之后,

 

3.#define定义宏

2中讲到了用#define来实现条件编译.实际上用#define还可以定义些宏,相当于起替换作用.

例如#define  PI 3.14

你在代码中就可以用PI来代替3.14使用了.在C中使用这样的宏很多.但在C++中是不建议过多的使用宏的.如果像上面宏定义一般在C++中应该用一个const常量.而如果是用宏定义一个简单函数,则一般建议用内联函数(inline)

 

4.#progma

progma一个用处是隐藏一些编译时的警告信息.不过这个应该不常用.如果你用VS的话常用的是#progma once .可以防止头文件被多次编译.与这样定义宏的作用一样

#ifndef _HEADER #define _HEADER .... #endif

不过貌似#progma并不是所有的编译器支持吧.你用VS时没问题,如果代码放到另外一个编译器去可能不识别了.

另外还有个#progma region可以起到注释的时候

比如#progma region       this function is used for connecting oracle

     //some source code

#end region

你这样写之后在VS的开发环境中,就会在最左边的边界显示加减号,你可以点击展开或收缩这一堆代码,收缩时只显示this function....这些信息,相当于是注释信息.当然#progma region跟#progma once一样在其他编译器中未必支持

 

C#常用预处理指令

C#中的预处理语法跟C++差不多,但用的不多,有些功能可以用特性(attribute)实现,而且attribute的功能更强大.当然有些地方还是会用到预处理.

由于C#中没有头文件,所以也没有#include这指令.在C#中用的比较多的还是条件编译.用法几乎跟C++一模一样.只有一个小区别,C++中用#ifdef来判断而C#更简单,直接用#if

然后像C++中#define PI 3.14这样定义一个宏,在C#中不能使用了,会当作错误处理

 

#progma 的话还可以用来隐藏警告信息

比如#progma warning disable 438

//some code

#progma warning restore 438

处于中间的那些代码如果出现438类型的警告就不报出来.其他地方还是会提示警告.

 

#region

//code

#endregion

这个东东和C++中的#progma region作用完全一样.而且#region是C#语言规范中规定的语法.说到注释我想说点题外话,怎么写好注释

 

怎么写好注释

可能我们大部分人都会经常听说注释多重要.看没有注释的的代码是件痛苦的事.当我自己在工作中实际接触到一百多万行的代码时感触更深.

一说到注释我们最容易联想到的是/* this is comments*/      或者//this is comments            这样的狭义上的注释. 也是我们最常用到的注释.也确实是非常必要,不可缺少的.但实际上你会发现,如果源代码超级多了,你还加很多这样的的注释进去会严重干扰我们看代码的.所以这样的注释一多还会起了负面作用.所以实际工作中,这样的注释写是一定要写,但要把握一个度,只有一些逻辑性比较强,不写注释不容易看懂的地方才加注释.

而我们要多写广义上的注释.就是命名类,函数,变量时尽量用一些有实际含义的英语单词.让人家一看就明白这类和函数是干嘛的,这种自解释的命名是最好的注释.另外项目代码一多,你如果埋头看代码可能会分不清方向.此时就会意识到设计文档是多么重要了啊.看下设计文档就对整个项目有个大概的了解,知道大的方向,才不会陷入代码的具体细节中.而且面向对象语言很好的把代码模块化了.一个大项目往往是一个solution下面很多project,然后project下面很多类.看了设计文档后知道每个project大概是干嘛的,各个project间怎么交互的.然后就可以有针对性的去看代码了.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在 C++ 中调用 C# DLL,您需要使用 C++/CLI 中介。C++/CLI 是一种 C++ 扩展,可以让您使用 .NET 类型和对象。这意味着您可以编写 C++/CLI 代码来调用 .NET 程序集中的类和方法。 下面是一个简单的示例,展示了如何使用 C++/CLI 从 C++ 中调用 C# DLL 中的方法。 首先,您需要编写 C++/CLI 包装器类,该类将调用 C# DLL 中的方法。例如,假设您的 C# DLL 包含一个名为 `MyClass` 的类,并且该类有一个名为 `MyMethod` 的方法,您可以编写以下 C++/CLI 代码: ```cpp #pragma once using namespace System; using namespace System::Runtime::InteropServices; namespace MyNamespace { public ref class MyClassWrapper { private: IntPtr m_handle; public: MyClassWrapper() { m_handle = LoadLibrary("MyDll.dll"); } ~MyClassWrapper() { FreeLibrary((HMODULE)m_handle.ToPointer()); } int MyMethod(int arg1, int arg2) { typedef int(__stdcall *MyMethodFunc)(int, int); MyMethodFunc myMethod = (MyMethodFunc)GetProcAddress((HMODULE)m_handle.ToPointer(), "MyMethod"); return myMethod(arg1, arg2); } }; } ``` 这个包装器类将加载 C# DLL 并调用 `MyMethod` 方法。请注意,`MyMethod` 方法的签名必须与 C# DLL 中的方法签名匹配。在此示例中,假设 `MyMethod` 是一个 `int` 返回类型的方法,它接受两个 `int` 参数。 接下来,您需要在 C++ 代码中使用 C++/CLI 包装器类。例如,您可以编写以下 C++ 代码: ```cpp #include <iostream> #include "MyClassWrapper.h" using namespace std; using namespace MyNamespace; int main() { MyClassWrapper^ wrapper = gcnew MyClassWrapper(); int result = wrapper->MyMethod(1, 2); cout << "Result: " << result << endl; return 0; } ``` 这将创建一个 `MyClassWrapper` 对象,并调用 `MyMethod` 方法。请注意,您需要使用 `^` 符号来声明包装器类的引用。 最后,您需要使用 CMake 编译您的代码。您需要确保将 C++/CLI 文件添加到项目中,并将 C# DLL 文件添加到可执行文件的目录中。例如,您可以编写以下 CMakeLists.txt 文件: ``` cmake_minimum_required(VERSION 3.10) project(MyProject) set(CMAKE_CXX_STANDARD 11) add_executable(MyExecutable main.cpp MyClassWrapper.cpp) set_property(TARGET MyExecutable PROPERTY VS_DOTNET_REFERENCES "MyDll.dll" ) configure_file(MyDll.dll MyDll.dll COPYONLY) ``` 这将编译您的代码,并将 `MyDll.dll` 复制到可执行文件的目录中。 希望这可以帮助您开始在 C++ 中调用 C# DLL。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值