由于要基于开发包开发SDK。因此需要在C#中调用VC做的SDK开发接口。及在C#中调用动态链接库DLL文件。
C#调用动态链接库有两种方式,一种是直接引用COM,直接add Reference加入工程。另外一种就是DllImport。这里我们用的后者。
引用其实很简单。
加入空间集
using System.Runtime.InteropServices;
然后定义一个类,在该类中转换VC的方法,转换成C#。
class CanonCamera
{
[DllImport("..\\..\\Lib\\PRSDK.dll")]
public static extern uint PR_StartSDK();
[DllImport("..\\..\\Lib\\PRSDK.dll", CharSet = CharSet.Ansi)]
public static extern uint PR_GetDllsVersion(
ref uint pBufferSize,
ref prType.prDllsVerInfo pDllVersion
);
}
然后直接调用就好了。用法比较简单。但转换起来就比较的难一些,原因就是VC中关于指针,数组,还有结构的定义与C#都不太一样。特别是结构,需要非托管的方式。
typeof unsigned long prUInt32;
prCAPI PR_GetDllsVersion(
prUInt32* pBufferSize,
prDllsVerInfo* pDllVersion
);
对于VC中 int* a,这种指针的输入参数,在C#中可以采用ref方式传递参数。及 ref int a;
结构。转换时要特别注意
在VC中定义一个结构
typedef struct{
prWChar ModuleName[512]; /* Module name (512 characters) */
prWChar Version[32]; /* Version (32 characters) */
}prVerInfo;
typedef struct{
prUInt32 Entry; /* Number of modules included in this structure */
prVerInfo VerInfo[1]; /* Array of file version number information of PS-ReC SDK modules */
}prDllsVerInfo;
那么在C#中需要这样定义
[StructLayout(LayoutKind.Sequential)]
public struct prVerInfo{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)]
public ushort[] ModuleName; /* Module name (512 characters) */
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public ushort[] Version; //32 characters
}
[StructLayout(LayoutKind.Sequential)] //顺序布局
public struct prDllsVerInfo {
public uint Entry;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] //在托管代码和非托管代码之间封送数据
public prVerInfo[] VerInfo; //prANY
};
好了,这样就可以调用SDK函数了
prDllsVerInfo prDllVerInfo = new prDllsVerInfo();
err = CanonCamera.PR_GetDllsVersion(ref buffersize, ref prDllVerInfo); //ok
今日收获,基本的值类型这些要清楚。
VC unsigned long c# uint ulong System.UInt32; //32位
VC unsigned shot c# ushot System.UInt16; //16位
感觉C#学了半天,基本的都忘记了。
另外一个ASCII和字符串互相转换的函数。
public string Chr(int asciiCode)
{
if (asciiCode >= 0 && asciiCode <= 255)
{
System.Text.ASCIIEncoding asciiEncoding = new System.Text.ASCIIEncoding();
byte[] byteArray = new byte[] { (byte)asciiCode };
string strCharacter = asciiEncoding.GetString(byteArray);
return (strCharacter);
}
else
{
//throw new Exception("ASCII Code is not valid.");//汉字
return "不正常";
}
}
public int Asc(string character)
{
if (character.Length == 1)
{
System.Text.ASCIIEncoding asciiEncoding = new System.Text.ASCIIEncoding();
int intAsciiCode = (int)asciiEncoding.GetBytes(character)[0];
return (intAsciiCode);
}
else
{
throw new Exception("Character is not valid.");
}
}