从C#调用C DLL
|
我正在尝试从C#调用C DLL,但是我没有任何乐趣。 DLL的文档提供了VB的示例函数声明,如下所示:
Declare Function TransGeogPt Lib \"c:\\DLLS\\GDAit.dll\" (ByVal sGridFile As String, ByVal lDirection As
Long, ByVal dLat As Double, ByVal dLong As Double, pdLatNew As Double, pdLongNew As Double,
pdLatAcc As Double, pdLongAcc As Double) As Long
Declare Function TransProjPt Lib \"c:\\DLLS\\GDAit.dll\" (ByVal sGridFile As String, ByVal lDirection As
Long, ByVal dLat As Double, ByVal dLong As Double, ByVal lZone As Long, pdLatNew As Double,
pdLongNew As Double, pdLatAcc As Double, pdLongAcc As Double) As Long
因此,我做了以下工作:
public class GDAIt
{
public static string gridFileName = @\"C:\\Nat84.gsb\";
[DllImport(@\"c:\\GDAit.dll\")]
public static extern long TransGeogPt(string sGridFile, long lDirection, double dLat, double dLong, ref double pdLatNew, ref double pdLongNew, ref double pdLatAcc, ref double pdLongAcc);
[DllImport(@\"c:\\GDAit.dll\")]
public static extern long TransProjPt(string sGridFile, long lDirection, double dLat, double dLong, long lZone, ref double pdLatNew, ref double pdLongNew, ref double pdLatAcc, ref double pdLongAcc);
public static long CallTransGeogPt(string sGridFile, long lDirection, double dLat, double dLong, ref double pdLatNew, ref double pdLongNew, ref double pdLatAcc, ref double pdLongAcc)
{
return TransGeogPt(sGridFile, lDirection, dLat, dLong, ref pdLatNew, ref pdLongNew, ref pdLatAcc, ref pdLongAcc);
}
public static long CallTransProjPt(string sGridFile, long lDirection, double dLat, double dLong, long lZone, ref double pdLatNew, ref double pdLongNew, ref double pdLatAcc, ref double pdLongAcc)
{
return TransProjPt(sGridFile, lDirection, dLat, dLong, lZone, ref pdLatNew, ref pdLongNew, ref pdLatAcc, ref pdLongAcc);
}
public static void Process()
{
double latitude = 0.0;
double longitude = 0.0;
double latAcc = 0.0;
double longAcc = 0.0;
long result = 0;
result = CallTransProjPt(gridFileName,
1,
394980,
7619799,
51,
ref latitude,
ref longitude,
ref latAcc,
ref longAcc);
Console.WriteLine(string.Format(\"Result was {0}, Lat: {1}, Long: {2}\", result, latitude, longitude));
int error = Marshal.GetLastWin32Error();
Console.WriteLine(string.Format(\"Last error recieved was {0}\", error));
}
}
我仍然不太走运,并且尝试了DLLImport语句中的其他各种设置,例如;
SetLastError = true,CharSet = CharSet.Auto,CallingConvention = CallingConvention.Cdecl)
我从代码中得到的输出是;
Result was 4690529317195612196, Lat: 0, Long: 0
Last error recieved was 6
如果我正确地查看有关Win32错误的信息,我认为这是指的。
ERROR_INVALID_HANDLE句柄无效。
6(0x6)
我的猜测是将文件名作为字符串传递是否存在问题,或者我通过ref传递双精度数的方式吗?但是,我真的不知道,而且我对如何进一步调查该问题不知所措。
任何想法都非常感谢。
谢谢。
没有找到相关结果
已邀请:
4 个回复
傻寺俊擒
当将其输入到Interop助手工具中时,它表明而不是使用long(就像我在原始问题中所做的那样),这些应该声明为int。它产生以下输出,这意味着我上面的代码现在可以按我希望的那样工作了。好极了。
谢谢大家的帮助。
膏焦凑
我还将背负Mark Sowul的回答,并说尝试使用StdCall而不是Cdecl进行调用。 另外,作为预防措施,我可能会仔细检查以确保编译器设置为编译x86代码,以防它编译为64位。
宦哨抹存胳
更改为
C ++的字符串种类繁多,以至于在管理和非托管代码之间编排字符串可能很棘手。
骂狮淋唐便