由於要基於開發包開發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.");
}
}