C# 调用C++ DLL (一)

C++方法封装成dll及C#调用示例 阅读详情

在合作开发时,C#时常需要调用C++DLL,当传递参数时时常遇到问题,尤其是传递和返回字符串是,现总结一下,分享给大家:

VC++中主要字符串类型为:LPSTR,LPCSTR, LPCTSTR, string, CString, LPCWSTR, LPWSTR等
但转为C#类型却不完全相同。

主要有如下几种转换:


将string转为IntPtr:IntPtr System.Runtime.InteropServices.Marshal.StringToCoTaskMemAuto(string)

将IntPtr转为string:string System.Runtime.InteropServices.MarshalPtrToStringAuto(IntPtr)

类型对照:

BSTR ---------  StringBuilder

LPCTSTR --------- StringBuilder

LPCWSTR ---------  IntPtr

handle---------IntPtr

hwnd-----------IntPtr

char *----------string

int * -----------ref int

int &-----------ref int

void *----------IntPtr

unsigned char *-----ref byte

Struct需要在C#里重新定义一个Struct

CallBack回调函数需要封装在一个委托里,delegate static extern int FunCallBack(string str);

注意在每个函数的前面加上public static extern +返回的数据类型,如果不加public ,函数默认为私有函数,调用就会出错。


在C#调用C++ DLL封装库时会出现两个问题:


1. 数据类型转换问题 
2. 指针或地址参数传送问题

    首先是数据类型转换问题。因为C#是.NET语言,利用的是.NET的基本数据类型,所以实际上是将C++的数据类型与.NET的基本数据类型进行对应。

    例如C++的原有函数是:

int __stdcall FunctionName(unsigned char param1, unsigned short param2)

    其中的参数数据类型在C#中,必须转为对应的数据类型。如:

[DllImport(“ COM DLL path/file ”)] 
extern static int FunctionName(byte param1, ushort param2)

    因为调用的是__stdcall函数,所以使用了P/Invoke的调用方法。其中的方法FunctionName必须声明为静态外部函数,即加上extern static声明头。我们可以看到,在调用的过程中,unsigned char变为了byte,unsigned short变为了ushort。变换后,参数的数据类型不变,只是声明方式必须改为.NET语言的规范。

    我们可以通过下表来进行这种转换:

Win32 Types 
CLR Type

char, INT8, SBYTE, CHAR 
System.SByte

short, short int, INT16, SHORT 
System.Int16

int, long, long int, INT32, LONG32, BOOL , INT 
System.Int32

__int64, INT64, LONGLONG 
System.Int64

unsigned char, UINT8, UCHAR , BYTE 
System.Byte

unsigned short, UINT16, USHORT, WORD, ATOM, WCHAR , __wchar_t
System.UInt16

unsigned, unsigned int, UINT32, ULONG32, DWORD32, ULONG, DWORD, UINT
System.UInt32

unsigned __int64, UINT64, DWORDLONG, ULONGLONG 
System.UInt64

float, FLOAT 
System.Single

double, long double, DOUBLE 
System.Double


    之后再将CLR的数据类型表示方式转换为C#的表示方式。这样一来,函数的参数类型问题就可以解决了。

    现在,我们再来考虑下一个问题,如果要调用的函数参数是指针或是地址变量,怎么办?

    对于这种情况可以使用C#提供的非安全代码来进行解决,但是,毕竟是非托管代码,垃圾资源处理不好的话对应用程序是很不利的。所以还是使用C#提供的ref以及out修饰字比较好。

    同上面一样,我们也举一个例子:

int __stdcall FunctionName(unsigned char &param1, unsigned char *param2)

    在C#中对其进行调用的方法是:

[DllImport(“ file ”)] 
extern static int FunctionName(ref byte param1, ref byte param2)

    看到这,可能有人会问,&是取地址,*是传送指针,为何都只用ref就可以了呢?一种可能的解释是ref是一个具有重载特性的修饰符,会自动识别是取地址还是传送指针。

    在实际的情况中,我们利用参数传递地址更多还是用在传送数组首地址上。 
如:byte[] param1 = new param1(6);

    在这里我们声明了一个数组,现在要将其的首地址传送过去,只要将param1数组的第一个元素用ref修饰。具体如下:

[DllImport(“ file ”)] 
extern static int FunctionName(ref byte param1[1], ref byte param2) 
  
文章出处:DIY部落(http://www.diybl.com/course/3_program/c++/cppjs/200886/134816.html)

C# 中调用DLL

为了能用上原来的C++代码,只好研究下从C# 中调用DLL
首先必须要有一个声明,使用的是DllImport关键字: 
包含DllImport所在的名字空间 
using System.Runtime.InteropServices; 
public class XXXX{

[DllImport(“MyDLL.dll")]
public static extern int mySum (int a,int b); 
}


[DllImport(“MyDLL.dll")] 
public static extern int mySum (int a,int b); 
代码中DllImport关键字作用是告诉编译器入口点在哪里,并将打包函数捆绑在这个类中 
在调用的时候 
在类中的时候 直接   mySum(a,b);就可以了 
在其他类中调用: XXXX. mySum(a,b); 

[DllImport(“MyDLL.dll”)]在申明的时候还可以添加几个属性 
[DllImport(“MyDLL.dll", EntryPoint=" mySum ",CharSet=CharSet.Auto,CallingConvention=CallingConvention.StdCall)
] 
EntryPoint: 指定要调用的 DLL 入口点。默认入口点名称是托管方法的名称 。 
CharSet: 控制名称重整和封送 String 参数的方式 (默认是UNICODE) 
CallingConvention指示入口点的函数调用约定(默认WINAPI)(上次报告讲过的) 
SetLastError 指示被调用方在从属性化方法返回之前是否调用 SetLastError Win32 API 函数 (C#中默认false )


int 类型 
[DllImport(“MyDLL.dll")] 
//返回个int 类型 
public static extern int mySum (int a1,int b1); 
//DLL中申明 
extern “C” __declspec(dllexport)  int WINAPI mySum(int a2,int b2) 
{ 
//a2 b2不能改变a1 b1
//a2=..
//b2=...
return a+b; 
}

//参数传递int 类型 
public static extern int mySum (ref int a1,ref int b1); 
//DLL中申明 
extern “C” __declspec(dllexport)  int WINAPI mySum(int *a2,int *b2) 
{ 
//可以改变 a1, b1
*a2=...
*b2=...
return a+b; 
} 


DLL 需传入char *类型 
[DllImport(“MyDLL.dll")] 
//传入值 
public static extern int mySum (string  astr1,string bstr1); 
//DLL中申明 
extern “C” __declspec(dllexport)  int WINAPI mySum(char * astr2,char * bstr2) 
{ 
//改变astr2 bstr 2  ,astr1 bstr1不会被改变
return a+b; 
}


DLL 需传出char *类型 
[DllImport(“MyDLL.dll")] 
// 传出值
public static extern int mySum (StringBuilder abuf, StringBuilder bbuf ); 
//DLL中申明 
extern “C” __declspec(dllexport)  int WINAPI mySum(char * astr,char * bstr) 
{ 
//传出char * 改变astr bstr -->abuf, bbuf可以被改变
return a+b; 
} 

DLL 回调函数 

BOOL EnumWindows(WNDENUMPROC lpEnumFunc, LPARAM lParam) 

using System; 
using System.Runtime.InteropServices; 
public delegate bool CallBack(int hwnd, int lParam); //定义委托函数类型 
public class EnumReportApp 
{ 
[DllImport("user32")] 
public static extern int EnumWindows(CallBack x, int y); 
public static void Main() { 
CallBack myCallBack = new CallBack(EnumReportApp.Report); EnumWindows(myCallBack, 0);
} 
public static bool Report(int hwnd, int lParam) 
{ 
Console.Write("Window handle is "); 
Console.WriteLine(hwnd); return true; 
} 
} 

DLL  传递结构  
BOOL PtInRect(const RECT *lprc, POINT pt); 

using System.Runtime.InteropServices; 
[StructLayout(LayoutKind.Sequential)] 
public struct Point {
public int x; 
public int y;
} 
[StructLayout(LayoutKind.Explicit)] 
public struct Rect 
{ 
[FieldOffset(0)] public int left; 
[FieldOffset(4)] public int top;
[FieldOffset(8)] public int right; 
[FieldOffset(12)] public int bottom;
} 
Class XXXX { 
[DllImport("User32.dll")] 
public static extern bool PtInRect(ref  Rect r, Point p); 
}

DLL 回调函数,传递结构 想看的msdn里面都有专题介绍,看的我都是晕晕的:)

其他参考请搜索:

在C#程序设计中使用Win32类库
C#中调用C++托管Dll
如何在C#中加载自己编写的动态链接库

相关文章:Creating a P/Invoke Library


能用上DLL以后感觉还是很好的,原来的C++代码只要修改编译通过就可以了,
高兴没多久,发现.net2005居然可以用VB,VC开发智能设备项目,可以创建MFC智能设备项目
晕晕,难道可以直接用MFC来开发smartphone的程序了,赶紧看看,,,

Visual C++ 使用 __declspec(dllexport) 从 DLL 导出 (到C#)

由于各种的原因, 如何把unmanaged 的 c++ DLL 转换成 managed C# 是一个问题。

方法有3个.

Ø 使用.def文件

Ø 可以不用.def文件, 使用__declspec(dllexport)关键字, 特别是针对Visual C++编译器的时候

Ø 直接用MC++写

什么时候用.def文件?

.def的意思是module-definition, 这个纯文本的文件定义了模块的信息。 对于编译器来说, 一个方法在编译之后的DLL文件里, 存在的形式名字可能不是作者当时起的那个,例如好好的函数名字function() 变成了?function2@@YAXXZ; 可以用undname查看这个被编译器修饰掉的名字, 原型是"void __cdecl function2(void)". 大概使用的时候就会遇到类似”链接错误,未决的外部符号…” 的错误.

.def文件主要的作用, 就是”标注” 出这个函数原来的样子, 这样编译器在编译的时候, 规则上就会以C编译器的规则来处理, 修饰被去掉了, 另外同时可以把导出函数的序号值手动的改高一点; 还有一个优点(也是缺点) 就是可以用NONAME来修饰函数, 这样导出函数的序号值就变成了1~N, 即第N个函数. 所以调用GetProcAddress() 的时候, 可以直接用定义的序号值, 而不用写函数的名字(但是名字就完全不可用了), 更好的是, 导出函数的这个DLL会变得比较小, 当然, MSDN强调了一点: 仅你可以并有权更改这个.def文件内容的时候, 你才可以用这个办法.

那么, 什么时候考虑用.def文件呢? 因为编译器不同, 而产生的修饰名不同的话, 这个文件就是必须的.

注意如果文件没有导出函数的话, 这个文件可能降低运行效率。

.def文件的格式

LIBRARY FileNameWithoutExtension

EXPORTS

Function1 @1

Function3 @2

Function2 @3 NONAME

启用 Enable it: Property pages-> Configuration Properties->C/C++ -> Linker -> input -> Module Definition File

那不用.def呢? __declspec(dllexport)的作用

这个东西, 可以给函数用, 也可以给类用. 声明大概这样子:

 

__declspec(dllexport)int__stdcall GetMid(vector<type> ve);

class__declspec(dllexport) TestClass{

public:

TestClass();

}

这牵扯到了一个东西就是__stdcall和__cdecl (还有__fastcall, 不过很少用), 其中__cdecl一般是C或者C++的缺省调用规范, 但是最大的一个区别就是__stdcall在返回前自身清除堆栈, 而__cdecl是调用方来做这个事情(可参考COM中的某些机制), 另一个区别就是__stdcall对于可变参数的函数, 玩不转.

反正今时今日, 大家都在用__stdcall, 所以这么写也没什么问题, 但不是没有. VB里调用标记着__cdecl的方法, 可能会得到一个异常Bad DLL Calling Convention. 解决方法也很简单:

原来的函数

long_cdecl PassStr(LPSTRp Str)

{       return1;      }

新的函数

	
long_stdcall PassStrStdCall(LPSTRpStr)
{       returnPassStr(pStr);      }

问题是, 如果这个函数原型, 参数是可变的, 那又怎么弄呢?

调用的时候, C#都是这么写的:

[DllImport("", EntryPoint =@" ?GetMid@@YAXXZ", CharSet = CharSet.Auto)]
privatestaticexternvoidGetMid(...);

这个入口点名字还真别扭, 看来去掉这个修饰还是蛮需要的, 除了用.def文件, 另一个办法就是用 extern “C”.

Extern “C”

一句话总结:这个东西可以去掉修饰名。在不用.def文件的前提下, 这个可以保证你的函数function() 还是这个名字.

但是,这个东西对类不太起作用!

这个东西是这么用的: 放到函数声明的最前面。 就类似这样 extern “C” void __declspec(dllexport) function(void);

对于类, 一般的做法是, 把它的内部方法(特别是实例方法,或变量),wrap出一个方法来。 见下面的实例.

还要做什么?

当一个DLL被初始化的时候, 它需要一个入口点, 一般对于非MFC DLL来说, 这样写就行了:


BOOLAPIENTRY DllMain(HANDLEhModule, 

                      DWORD ul_reason_for_call, 

                      LPVOID lpReserved

                      )

{

    switch( ul_reason_for_call )

    {

    caseDLL_PROCESS_ATTACH:
    caseDLL_THREAD_ATTACH:

    caseDLL_THREAD_DETACH:

    caseDLL_PROCESS_DETACH:
12
        break;

    }

    returnTRUE;

}


要注意的是这个入口点的名字必须是DllMain, 如果不是需要修

改linker的/entry 选项. 否则对于C的话可能会初始化失败.

************************************************************************

开始用导出函数 PInvoke

为了好看一点, 先约定一下:

#define EXT_C extern "C" 

#define DLLEXPORT __declspec(dllexport)

#define EXT_C_DLLEXPORT EXT_C DLLEXPORT

#define CALLBACK    __stdcall

#define WINAPI      __stdcall

#define APIENTRY    WINAPI

1. 普通的函数

EXT_C_DLLEXPORT void WINAPI Function(); 
[DllImport("filename.dll", EntryPoint =" Function")] 
privatestaticexternvoidFunc();

2. ref或者out

EXT_C_DLLEXPORT void WINAPI Function(Type** ty);

[DllImport("filename.dll", EntryPoint =" Function")]
privatestaticexternvoidFunc(outType ty);

3. 指针函数和委托


Typedef void(CALLBACK *pFunc)(int); 
EXT_C_DLLEXPORT void WINAPI Compare(inta, intb, pFunc p);
privatedelegateintCompareCallback(inta, intb); 
[DllImport("filename.dll",EntryPoint=”Compare”)] 
privatestaticexternintCompare(inta, intb, CompareCallback call);

4. 类的处理. 其实不是说不可以把类标记为 DLLEXPORT, 如果可以的话, 当然是wrap比较好

C++里的原型

classDLLEXPORT Test{ 
public:Test();
 ~Test();
BOOLfunction(intpar) 
};

类被export, 函数调用时候注意用CallingConvention.ThisCall.

[DllImport("filename.dll", EntryPoint =@"??4Test@@QEAAAEAV0@AEBV0@@Z", CallingConvention = CallingConvention.ThisCall)]
privatestaticexternintTestFunc(IntPtr hwnd, intpar);

采用了”迂回”策略, C++里先这样定义,同理, 添加构造函数等, 函数就变成了这个样子:

EXT_C_DLLEXPORT BOOLWINAPI function_wrap(Test* t, int par) {
returnt->function(par); 
} 
EXT_C_DLLEXPORT Test* Test_ctor(){ 
 Test* t =newTest();
 returnt;
} 
EXT_C_DLLEXPORT voidTest_dector(Test* t){
 if(NULL == t)
  { 
     deletet;
      t = NULL; 
  }
}


在C#里这样写, 那么就和平时用没什么区别了.

publicclassTest : IDisposable

        {

            privateIntPtr instance;

            publicTest()

            {

                instance = CreateInstance();

            }

             ~Test()

            {

                Dispose(false);

            }

            #region pinvoke

            [DllImport("filename.dll", EntryPoint =@"Test_ctor")]

            privatestaticexternIntPtr CreateInstance();

            [DllImport("filename.dll", EntryPoint =@"Test_dector")]

            privatestaticexternvoidDestroyInstance(IntPtr hwnd);

            [return: MarshalAs(UnmanagedType.Bool)]

            [DllImport("filename.dll", EntryPoint =@"function_wrap")]

            privatestaticexternboolfunction_wrap(intpar);

            #endregion


            #region IDisposable Members


            publicvoidDispose()

            {

                Dispose(true);

            }


            privatevoidDispose(boolbDisposing)

            {

                if(instance != IntPtr.Zero)

                {

                    DestroyInstance(instance);

                }


                if(bDisposing)

                {

                    GC.SuppressFinalize(this);

                }

            }


            #endregion

        }


5. Struct操作.

typedefstructObject_HANDLE {
unsignedlong     dbch_size;
 HANDLE    dbch_handle;
 GUID       dbch_eventguid;
 BOOLres_flag;
} 
Object_Native_HANDLE ;

首先在C#里严格定义这个,LayoutKind.Sequential 用来保证内存分配的正常。

[StructLayout(LayoutKind.Sequential)] 
publicstructObject_Native_HANDLE{ 
  publiculongdbch_size;
  publicIntPtr dbch_handle; 
  publicGuid dbch_eventGuid; 
 publicboolres_flag; 
}

Marshal的使用如下:

1

Object_Native_HANDLE obj =newObject_Native_HANDLE(); //初始化

2

intamountToAllocate = Marshal.SizeOf(obj);//获取大小

3

IntPtr objPtr = Marshal.AllocHGlobal(amountToAllocate);//分配并获取空的空间地址

4

Marshal.StructureToPtr(obj, objPtr,false);// 值写入分配的空间

5

//操作...

6

Marshal.FreeHGlobal(objPtr);//释放空间

最后提一句, unmaged code中的错误, 到managed 以后, 极大可能是捕捉不到的。 所以错误需要分别处理。

花了不少时间, MC++平时用的不多, 不写了。

c#调用非托管C++生成的dll  最近在项目中碰到需要调用非托管C++生成的dll,下面将自己遇到的问题,以及解决的办法总结如下:  1.     问题:     我们通常去映射dll的方法是使用        public const string dllPath =path;                [DllImport(dllPath + "test.dll", EntryPoint = "test()", Se 阅读详情

相关推荐

C#调用C++的dll及MATLAB的dll的方法(一)

本机环境win7 64位,vs2013,MATLAB2015,讲一下在此环境下如何用C#调用C++的dll以及MATLAB的dll

做一个美丽又努力的程序媛 1591

C#时常需要调用C++DLL

在合作开发时,C#时常需要调用C++DLL,当传递参数时时常遇到问题,尤其是传递和返回字符串是,现总结一下,分享给大家: VC++中主要字符串类型为:LPSTR,LPCSTR, LPCTSTR, string, CString, LPCWSTR, LPWSTR等 但转为C#类

zhima159的专栏 1029

从零到一:VS2019中C++ DLL的跨语言调用实战(C#篇)

本文详细介绍了在VS2019中实现C++动态链接库(DLL)与C#的跨语言调用实战,涵盖P/Invoke与C++/CLI两种主流方案。通过环境配置、函数导出、复杂类型处理及性能对比等核心内容,帮助开发者高效解决工业控制和游戏开发中的高性能计算需求。

weixin_29011667的博客 320

C#分享辅助类:动态调用C++DLL(DynamicCallHandler)

【代码】C#分享辅助类:动态调用C++DLL(DynamicCallHandler)

lyp1215的专栏 425

C++ 之动态链接库DLL使用注意事项及C#调用详解

C++ 之动态链接库DLL使用注意事项及C#调用详解

yohnyang的博客 2382

某银行大数据分析平台之云原生架构

软考架构师论文

doudoudouy的博客 768

在C#调用C++的DLL简析(一)——生成非托管dll

经过一晚上的折腾,还是下点决心将些许的心得写下来,以免以后重复劳动。 C#与C/C++相比,前者的优势在于UI,后者的优势在于算法,C++下的指针虽然恶心,若使用得当还是相当方便的,最重要的问题是,市面上很多流行的开发工具库,几乎没有不支持C++的,但全面支持C#只能说是难得,在CPU发展到今天,若说C#的执行效率跟C++相比有很大的差距并不是那么靠谱,若非万不得已我还是宁愿用C

windren06的专栏 5992

STM32+ESP8266接入OneNet物联网平台全流程

MQTT协议是物联网设备与云平台通信的主流轻量级消息传输标准,其发布/订阅模型天然适配嵌入式资源受限场景;OneJSON作为中国移动OneNet平台定制的数据格式,在标准JSON基础上精简Schema、降低解析开销,显著提升STM32等MCU的处理效率。该技术组合兼顾安全性、低功耗与工程可量产性,广泛应用于环境监测、智能仪表、工业传感器等远程数据采集系统。实际落地需协同完成云平台物模型定义、Token动态认证、MQTT Topic严格构造、AT指令可靠交互及单总线传感器数据融合等关键环节。本文以DS18B2

u5v6w7的博客 1120

C# 调用C++封装的dll库函数的方法(一)

本章讲述:C#调用C++封装的dll库函数,以及使用注意事项,分两个章节说明; 注意事项:用 DllImport 属性修饰的方法必须具有 extern 修饰符。 1、使用步骤可分为:C++的dll文件导入、C++的dll函数重写、C#调用C++的函数: (1)导入库文件:C#中要引用C++的dll,需要使用函数“DllImport”,添加其作用域:using System.Runtime.InteropServices; DllImport属性应用于方法,要求最少要提供包含入口点的dll的名称。..

^@^lemon tea^@^ 9291

MATLAB自动驾驶(1)——预构建场景库

MATLAB自动驾驶(1)——预构建场景库

Ucicorn Gundam的博客 3265

2025趋势:经济学研究中AI多智能体系统的6大架构方向(AI应用架构师必藏)

多智能体系统(MAS)由多个相互作用的智能体组成,每个智能体具备自主决策能力、感知环境的能力和与其他智能体通信的能力。微观行为的精细化建模:智能体可被赋予异质的偏好函数、信息集和决策规则,模拟真实市场的多样性动态交互的涌现性分析:通过智能体间的局部互动(如交易、合作、竞争),观察宏观经济现象的涌现过程反事实政策实验:在虚拟环境中安全测试极端政策(如负利率、全民基本收入)的连锁反应实时自适应调整:智能体可通过机器学习持续优化策略,模拟经济系统的演化特性。

AI 领航者的博客 1424

ue4 C++ 调用 c# dll(一)

ue4中调用 C#的dll(一)——打包出C#的dll 1.使用VS新建一个类库 2.项目中–管理NuGet程序包,添加UnmanagedExports,安装好后如下。 3.配置解决方案的生成平台,这里我选了x64。 4.编译程序。 注意编译程序可能会出现下面的错误。 error : syntax error at token '{' in: { Testme 这是由于操作系统不是英文...

yycocl的博客 3442

Flexible H-Tree(灵活 H 树)与 Multi-Tap 时钟流程解析

通过灵活 H 树与多抽头技术的结合,复杂时钟架构可在保持电气对称性的同时适应不规则布局,为高性能、低功耗 SoC 设计提供高效的时钟网络解决方案。

weixin_45371279的博客 1914

c#调用c++ dll(一)

首先来说说c++中的dll 核心的一些知识 比较大的应用程序都由很多模块组成,这些模块分别完成相对独立的功能,它们彼此协作来完成整个软件系统的工作。可能存在一些模块的功能较为通用,在构造其它软件系统时仍会被使用。在构造软件系统时,如果将所有模块的源代码都静态编译到整个应用程序 EXE 文件中,会产生一些问题:一个缺点是增加了应用程序的大小,它会占用更多的磁盘空间,程序运行时也会消耗较大的内存空间...

weixin_34082854的博客 131

3DMax马克杯制作教程

01 在前视图创建一个【圆柱体】,设置参数,长度为32,高度为82;高度分段12、边数为16;如图所示。 02 点击鼠标右键,把圆柱体转换为可编辑多边形,如图所示。 03 在修改面板中,选择【多边形】层级,在视图中选择所示的面,使用缩放工具稍微缩小一点,如图所示。 04 点击【插入设置】,如图所示。 设置插入数量为2.5mm。 05 点击【挤出设置】,如图所示。 ...

youximoxingEDO的博客 3478

创建 Fiori Space 时看不到传输请求的根因与排查路径

摘要: 在创建Fiori Space时,若Transport字段下拉列表为空,通常是因为系统未找到符合要求的传输请求。主要原因是: 请求类型不匹配:需使用Customizing request而非Workbench request。 用户权限问题:当前用户需在请求下有可用的task。 客户端或系统不一致:请求需在当前客户端和正确系统(如后端)中创建。 解决方法: 在当前客户端和系统中新建Customizing request,确保包含用户task。 检查是否为前后端分离架构,确保请求创建在正确的系统。 验证

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 107

C#调用C++ DLL简析(一)——生成非托管dll

本文出自 “几缕萧雨锁清秋” 博客,请务必保留此出处http://joeyliu.blog.51cto.com/3647812/1289614 经过一晚上的折腾,还是下点决心将些许的心得写下来,以免以后重复劳动。 C#与C/C++相比,前者的优势在于UI,后者的优势在于算法,C++下的指针虽然恶心,若使用得当还是相当方便的,最重要的问题是,市面上很多流行

lysc_forever的专栏 852

LDO 上电过冲的根因

LDO在上电瞬间常出现短时过冲电压(3.4V-3.5V),可能损坏敏感器件。其根本原因是:低

硬核科技 293

C# 调用C++ dll问题总结一 ——无法找到dll

无法找到dll这个问题花费了我大概2天时间才搞定。 一般问题网上都有,我只提最关键一点: Win7 家庭版 是搞不定的。 只能用Win7旗舰版

u012329294的专栏 1555

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

PIC18F87J60引脚不足?用I2C扩展器NCA6416实现16路IO扩展

在嵌入式系统设计中,I2C总线凭借仅需两根信号线即可挂载多个从设备的特性,成为解决单片机引脚资源不足的经典方案。其核心原理是通过设备地址与寄存器读写机制,让主控芯片以极低的硬件开销实现对扩展I/O的控制。在工业控制与远程监测场景中,这种数字I/O扩展方式既能灵活增加继电器、传感器等外设接口,又能保持系统结构简洁。针对PIC18F87J60这类集成以太网控制器的单片机,当自带GPIO无法满足多路开关量与状态监测需求时,通过I2C挂载16位扩展器NCA6416BYHP,即可获得16路可独立配置的输入输出通道。本

weixin_34198762的博客 379

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

C#调用C++生成的dll获取CPU序列号(一)

之前我们讨论过如何用C#调用delphi生成的dll来获取计算机的

sunny906的专栏 1300

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

C#调用C/C++ 动态链接库DLL(一)

在一些应用系统中经常会用到C#调用C++的一些代码,特别是结构体、指针、引用等类型的传递。总结一下常用的一些类型传递。官方关于C#与C++互操作的文档 http://msdn.microsoft.com/en-us/library/ms173184.aspx,官方的一个例子:http://msdn.microsoft.com/en-us/library/ms173187.aspx。 1。 C#...

移动开发记录 494

在C#调用C++的DLL方法(一)生成非托管dll

C#与C/C++相比,前者的优势在于UI,后者的优势在于算法,C++下的指针虽然恶心,若使用得当还是相当方便的,最重要的问题是,市面上很多流行的开发工具库,几乎没有不支持C++的,但全面支持C#只能说是难得。在CPU发展到今天,若说C#的执行效率跟C++相比有很大的差距,并不是那么靠谱,若非万不得已我还是宁愿用C#来写代码,调试什么的也很方便。 不得已的情况下,要在C#下使用C++的函数或类,最...

weixin_33671935的博客 362
上一篇: ScrollRect滑动优化(二)--动态创建Item列表
下一篇: C# 调用C++ DLL (二)
Le_Sam
博客等级 码龄11年 342粉丝 53原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值