https://bbs.csdn.net/topics/390658401?depth_1-utm_source=distribute.pc_relevant.none-task-discussion_topic-BlogCommendFromBaidu-3&utm_source=distribute.pc_relevant.none-task-discussion_topic-BlogCommendFromBaidu-3
https://blog.csdn.net/lyxzjq918/article/details/49149795?locationNum=2&fps=1
https://www.cnblogs.com/rainbow70626/p/4886717.html
///
/// XML序列化某一类型到指定的文件
///
///
///
///
public static void SerializeToXml<T>(string filePath, T obj)
{
try
{
using (System.IO.StreamWriter writer = new System.IO.StreamWriter(filePath))
{
System.Xml.Serialization.XmlSerializer xs = new System.Xml.Serialization.XmlSerializer(typeof(T));
xs.Serialize(writer, obj);
}
}
catch (Exception ex)
{
}
}
///
/// 从某一XML文件反序列化到某一类型
///
/// 待反序列化的XML文件名称
/// 反序列化出的
///
public static T DeserializeFromXml<T>(string filePath)
{
try
{
if (!System.IO.File.Exists(filePath))
throw new ArgumentNullException(filePath + " not Exists");
using (System.IO.StreamReader reader = new System.IO.StreamReader(filePath))
{
System.Xml.Serialization.XmlSerializer xs = new System.Xml.Serialization.XmlSerializer(typeof(T));
T ret = (T)xs.Deserialize(reader);
return ret;
}
}
catch (Exception ex)
{
return default(T);
}
}
}
具体问题:对 PInvoke 函数“Demo!Demo.MyImgCSharp::CalcAllEigens”的调用导致堆栈不对称。原因可能是托管的 PInvoke 签名与非托管的目标签名不匹配。请检查 PInvoke 签名的调用约定和参数与非托管的目标签名是否匹配。
解决办法:C++定义的导出函数如下:
#ifndef DLLOUTAPI
#define DLLOUTAPI extern “C” __declspec(dllexport)
#else
#define DLLOUTAPI extern “C” __declspec(dllimport)
#endif
在C#端调用时添加声明
[DllImport(“MyImg.dll”,CallingConvention = CallingConvention.Cdecl)]
C++中结构体定义:
typedef struct // 平面
{
double time;
float normal[3];
float center[3];
} plane;
C++中方法声明:
public void GetPlanes(plane *planes, int size);
C#中结构体声明:注意数组大小的声明方式。
[StructLayout(LayoutKind.Sequential)]
public struct GPlane
{
public double timestamp;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public float[] normal;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public float[] center;
}
C#中方法声明:注意[In, Out]的使用表明传进来的数组会被修改。
[DllImport(LibFileName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
private static extern bool Pvr_getAirGlassPlanes([In, Out]GPlane[] plane, int size);
C#中调用该方法:
int size = 2;
GPlane[] plane = new GPlane[size];
Pvr_getAirGlassPlanes(plane, size);
原文链接:https://blog.csdn.net/fenggewan/article/details/88409551
C++ | C# | 备注 |
---|---|---|
char * | string | |
指针 | IntPTR | |
自定义结构体指针 TestStruct * struts |
IntPTR | TestStruct stTest = new TestStruct (); IntPtr structPtr = Marshal.AllocHGlobal(Marshal.SizeOf(stTest)); func(structPtr); |
自定义结构体数组 TestStruct * struts |
[In, Out]TestStruct [] struts | [In, Out]代表传进来,会被修改后再传出去。C#端举例: TestStruct [] structArray = new TestStruct [3]; func(structArray); |
自定义结构体数组 const TestStruct * struts |
TestStruct[] struts | 只需要传进来C#端举例: TestStruct [] structArray = new TestStruct [3]; func(structArray); |
自定义结构体数组 TestStruct * struts |
ref TestStruct struts | 先传进来再被修改后传出去 C#端举例: TestStruct [] structArray = new TestStruct [3]; func(ref structArray[0]); |
常用结构体数组 const cv::Rect * rois |
ref Rectangle rois | 只需要传进来 所需名称空间 using System.Drawing; C#端举例: List func(ref rois.ToArray()[0]); // 先转为数组,然后再传入数组的首地址 也可以参考上面的方法,直接用数组而不是List |
OpenCV图像 func(const uchar* srcImgData,const int rows,const int cols) |
func(IntPtr src, int rows, int cols) | C#端调用举例: Mat src= CvInvoke.Imread(path, ImreadModes.Grayscale); func(src.DataPointer, src.Height, src.Width) |
[DllImport("MyDll.dll")]
public static extern bool func(IntPtr structPtr);
//此处省略中间细节,显示如何调用
int count = 6;
int size = Marshal.SizeOf(typeof(TestStruct));
IntPtr structPtr = Marshal.AllocHGlobal(size * count);
TestStruct[] TestStructs = new TestStruct[count];
if (func(structPtr))
{
MessageBox.Show("Fail");
return;
}
for (int index = 0; index < count; index++)
{
// 两种方法都可以,推荐下面这一种,防止在64位系统中超出上限
// IntPtr ptr = (IntPtr)((UInt32)structPtr + index * size);
IntPtr ptr = (IntPtr)(structPtr.ToInt64() + index * size); // 推荐此种
TestStructs[index] = (TestStruct)Marshal.PtrToStructure(ptr, typeof(TestStruct));
}
Marshal.FreeHGlobal(structPtr);
ref: 既进且出:在调用前,实参必须赋初始值。
out: 只出不进:在调用前,实参可以不赋初始值。
https://www.cnblogs.com/bedfly/p/12127435.html
https://www.cnblogs.com/QingYiShouJiuRen/p/11353896.html
https://www.cnblogs.com/motao9527/p/10220445.html
https://www.cnblogs.com/jixin/p/4727505.html改变
C++:
cv::Scalar borderValue = cv::Scalar()
C#:
MCvScalar borderValue = new Emgu.CV.Structure.MCvScalar();