先巩固复习语言的分类:Program Errors(程序错误)
Forbidden Behaviors(禁止行为)
程序在设计的时候会定义一组 forbidden behaviors,包括了所有的 untrapped errors,可能包括 trapped errors。
Well behaved、ill behaved
well behaved: 如果程序的执行不可能出现 forbidden behaviors,则称为 well behaved
ill behaved: 只要有可能出现 forbidden behaviors,则称为 ill behaved
从图中可以看出,绿色的 program 表示所有程序(所有程序,你能想到和不能想到的),error 表示出错的程序,error 不仅仅包括 trapped error 和 untrapped error。
根据图我们可以严格的定义动态类型,静态类型;强类型,弱类型
.h文件
#ifndef __CppDynamic__
#define __CppDynamic__
extern "C" __declspec(dllexport) int __stdcall Max(int a, int b, int c);
#endif
.cpp文件
#include "CppDynamic.h"
__declspec(dllexport) int __stdcall Max(int a, int b, int c)
{
int tmp = a > b ? a: b;
return tmp > c ? tmp : c;
}
关键词解析:
1.extern "C"
主要作用就是为了能够正确实现C++代码调用其他C语言代码。加上extern "C"后,会指示编译器这部分代码按C语言(而不是C++)的方式进行编译。由于C++支持函数重载,因此编译器编译函数的过程中会将函数的参数类型也加到编译后的代码中,而不仅仅是函数名;而C语言并不支持函数重载,因此编译C语言代码的函数时不会带上函数的参数类型,一般只包括函数名。
2.__declspec
declspec用于指定所给定类型的实例的与Microsoft相关的存储方式。其它的有关存储方式的修饰符如static与extern等是C和 C++语言的ANSI规范,而declspec是一种扩展属性的定义。扩展属性语法简化并标准化了C和C++语言关于Microsoft的扩展。
3.dllexport
用于dll导出函数
4.__stdcall
标准调用方式
从Debug文件夹将Dll文件和pdb文件导入unity中(并设置相关平台)
C#代码:
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
using UnityEngine;
using Debug = UnityEngine.Debug;
//定义对应的函数名调用dll接口
public class CppTest
{
[DllImport("CppDynamic")]
public static extern int Max(int a, int b, int c);
}
public class CppTestter : MonoBehaviour
{
void Start()
{
Debug.Log(CppTest.Max(1, 2, 3));
}
int MaxCS(int a, int b, int c)
{
int tmp = a > b ? a : b;
return tmp > c ? tmp : c;
}
//效率测试
public void Test()
{
Stopwatch sw = new Stopwatch();
for (int i = 0; i < 1000000; i++)
{
sw.Start();
MaxCS(1, 2, 3);
sw.Stop();
}
Debug.Log(sw.ElapsedMilliseconds);
sw.Reset();
for (int i = 0; i < 1000000; i++)
{
sw.Start();
CppTest.Max(1, 2, 3);
sw.Stop();
}
Debug.Log(sw.ElapsedMilliseconds);
}
}