c#学习笔记
PInvoke互操作技术
代码编写
- c++编写
--- Person.cpp
extern "C"
{
_declspec(dllexport) int Sum(int a, int b);
}
--- Person.h
#include "Person.h"
#include "iostream"
using namespace std;
int Sum(int a, int b)
{
return a + b;
}
- c#调用
class Program
{
[DllImport("ConsoleApplication1.dll", CallingConvention = CallingConvention.Cdecl)]
extern static int Sum(int a, int b);
static void Main(string[] args)
{
var result = Sum(10, 20);
Console.WriteLine($"10+20={result}");
Console.ReadLine();
}
}
---- output -----
10+20=30
- c#编写,c++调用
--- main.cs
class Program
{
delegate void Callback(int a);
[DllImport("ConsoleApplication1.dll", CallingConvention = CallingConvention.Cdecl)]
extern static void AsyncProcess(Callback callback);
static void Main(string[] args)
{
AsyncProcess((i) =>
{
//这里回调函数哦...
Console.WriteLine($"这是回调函数哦: {i}");
});
Console.ReadLine();
}
}
------- output -------
这是回调函数哦: 10
--- Person.cpp
extern "C"
{
//函数指针
typedef void(_stdcall* PCALLBACK) (int result);
_declspec(dllexport) void AsyncProcess(PCALLBACK ptr);
}
--- Person.h
#include "Person.h"
#include "iostream"
using namespace std;
void AsyncProcess(PCALLBACK ptr)
{
ptr(10); //回调C#的委托
}
-
传入c++里的内存由c#的垃圾回收器负责释放
-
当 C++ 函数在堆上分配内存时,内存的释放责任由调用者负责,而不是由 C++ 函数本身负责
环境配置
- 用vs2019创建C++的Console App,修改两个配置: 将程序导出为dll,修改成compile方式为Compile as C++ Code (/TP)
c#访问控制
- c#中的成员函数、变量必须保持与类前定义权限一致,与c++相比,必须在类前加访问控制
一般情况(4种)
- public:public关键字表示类成员对外部代码是完全可见和可访问的。即其他类或代码可以直接访问标记为public的成员。这是最开放的访问级别
- private:private关键字表示类成员只能在当前类内部访问,其他类无法访问标记为private的成员。这实现了数据隐藏和封装,确保类的实现细节对外部代码是不可见的
- protected:protected关键字表示类成员只能在当前类内部和其子类中访问。这允许继承体系中的子类访问基类的受保护成员,但对于其他类仍然是不可见的
- internal:internal关键字表示类成员只能在当前程序集内部访问。这个访问级别对于模块化代码和库的内部实现很有用,它允许不同的程序集使用相同的internal成员,但对于其他程序集是不可见的
特殊情况(2种)
- protected internal:protected internal关键字表示类成员可以在当前程序集内部和其子类中访问。它是protected和internal的结合,对于继承体系中的子类和同一程序集的其他类都是可见的。
- private protected:private protected关键字表示类成员可以在同一程序集内部和其派生类中访问,但是对于其他程序集的类是不可见的。它是private和protected的结合
c#标准
c++ & c# 数据结构对比
c++ | c # |
---|---|
vector | List |
map | SortedDictionary<TKey, TValue> |
set | HashSet |
queue | Queue |
stack | Stack |
priority_queue | PriorityQueue |
deque | LinkedList |
unordered_map | Dictionary<TKey, TValue> |
c#语法
- 更改字符串的值
char[] chs= s.ToCharArray();
chs[3] = '小';
s = new string(chs);
- enum
public enum NGType
{
拔针不良 = 10,
极耳错位 = 1,
极耳NG = 2,
读码NG=3,
外观AI不良=4
}
/// idx访问(按排列 不按val)
for(int i = 0; i < 5; ++i)
Console.WriteLine("{0}\t", (NGType)i);
int idx = 1;
// output:
拔针不良 极耳错位 极耳NG 读码NG 外观AI不良
- io相关
// Environment.CurrentDirectory;
string currentDir = Environment.CurrentDirectory;
Console.WriteLine("Current directory: " + currentDir);
// 设置当前工作目录
string newDir = @"C:\Temp";
Environment.CurrentDirectory = newDir;
Console.WriteLine("New current directory: " + Environment.CurrentDirectory);
// 在新的工作目录下读取文件(假设 C:\Temp 目录下有一个 test.txt 文件)
string filePath = "test.txt";
string fullPath = System.IO.Path.Combine(Environment.CurrentDirectory, filePath);
string content = System.IO.File.ReadAllText(fullPath);
Console.WriteLine("File content: " + content);
// FileInfo
// 文件路径
string filePath = @"C:\Temp\example.txt";
// 实例化 FileInfo 对象
FileInfo fileInfo = new FileInfo(filePath);
// 获取文件信息
Console.WriteLine("File Name: " + fileInfo.Name);
Console.WriteLine("File Full Path: " + fileInfo.FullName);
Console.WriteLine("Directory: " + fileInfo.Directory);
Console.WriteLine("File Size: " + fileInfo.Length + " bytes");
Console.WriteLine("Creation Time: " + fileInfo.CreationTime);
Console.WriteLine("Last Write Time: " + fileInfo.LastWriteTime);
// 文件复制和移动
string destinationPath = @"C:\Temp\newExample.txt";
fileInfo.CopyTo(destinationPath, true); // true 表示如果目标文件存在,则覆盖
fileInfo.MoveTo(@"C:\Temp\MovedExample.txt");
// 文件删除
fileInfo.Delete();
- 委托 delegate
- 可以让你将方法作为参数传递给其他方法,或者在特定条件下执行多个方法
// 委托类型声明
delegate int MyDelegate(int x, int y);
// 创建委托实例,并绑定方法
MyDelegate myDelegate = new MyDelegate(Add);
int result = myDelegate(5, 10); // 调用委托实例,执行绑定的方法
Console.WriteLine("Addition Result: " + result);
// 绑定多个方法,创建委托链
myDelegate += Subtract;
myDelegate += Multiply;
myDelegate += Divide;
// 调用委托链,依次执行绑定的方法
result = myDelegate(20, 5);
Console.WriteLine("Result of Delegate Chain: " + result);
- System.Text.StringBuilder
- 相当于c++里的string
System.Text.StringBuilder sb = new System.Text.StringBuilder("Rat: the ideal pet");
sb[0] = 'C';
System.Console.WriteLine(sb.ToString());
//Outputs Cat: the ideal pet
- enum遍历
foreach (DaysOfWeek day in Enum.GetValues(typeof(DaysOfWeek)))
{
Console.WriteLine($"{day}: {(int)day}");
}
- get,set自定义逻辑获值赋值
public class Person
{
private string name;
public string Name
{
get
{
return name;
}
set
{
// 可以在 set 方法中加入逻辑,例如验证输入值是否合法
if (!string.IsNullOrEmpty(value))
{
name = value;
}
else
{
Console.WriteLine("Name cannot be empty.");
}
}
}
}
-
GC(Garbage Collection)
-
是.NET Framework(或.NET Core)中的一种自动内存管理机制,它负责自动回收不再使用的内存,并释放给操作系统。以下是.NET Framework 中的常见 GC 过程:
-
标记阶段(Marking Phase):GC 会从根对象开始,通过遍历对象图(Object Graph)来标记所有可达的对象。根对象包括全局变量、静态变量以及当前线程的栈上的变量。所有可达的对象会被标记为“存活”。
-
清理阶段(Sweeping Phase):在标记阶段后,GC 会扫描堆中的所有对象,清理未被标记的对象。未被标记的对象被认为是“垃圾”,会被回收。
-
压缩阶段(Compacting Phase):在清理阶段后,GC 会对堆中的存活对象进行压缩,将它们移动到一侧,从而使得堆空间变得更加连续,减少内存碎片化问题。
-
释放阶段(Release Phase):在压缩阶段后,GC 会将不再使用的堆内存释放给操作系统,使得这些内存可以被其他进程或应用程序使用。
-
-
GC 过程是非常复杂的,并且.NET Framework 提供了不同的 GC 实现(如标记-清除、标记-压缩、并发 GC 等),以适应不同的场景和需求
-
-
泛型
- 类似与c++的模板类
// Declare the generic class.
public class GenericList<T>
{
public void Add(T input) { }
}
本文来自博客园,作者:InsiApple,转载请注明原文链接:https://www.cnblogs.com/InsiApple/p/17570593.html