gpt4 book ai didi

c# - 从 C# 调用 C DLL

转载 作者:太空狗 更新时间:2023-10-29 16:53:07 34 4
gpt4 key购买 nike

我正在尝试从 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 传递 double 值的方式有问题?但是,我真的不知道,而且我不知道如何进一步调查这个问题。

非常感谢任何想法。

谢谢。

最佳答案

我通过使用一个名为的工具找到了尝试失败的原因; Microsoft(R) P/Invoke Interop Assistant正如 an answer on this thread 所建议的那样.

我利用这个工具输入了一些 C 函数原型(prototype),并让它为我生成所需的 C# 原型(prototype)。 C 原型(prototype)如下所示;

long __stdcall TransProjPt(LPSTR psGridFile, long lDirection, double dEasting, double
dNorthing, long lZone, double* pdEastNew, double* pdNorthNew, double* pdEastAcc,
double* pdNorthAcc)

将此输入到 Interop 助手工具时,它表明不应使用 long(如我在原始问题中所做的那样),而应将其声明为 int。它产生了以下输出,这意味着我上面的代码现在可以正常工作了。是的。

    /// Return Type: int
///psGridFile: LPSTR->CHAR*
///lDirection: int
///dEasting: double
///dNorthing: double
///lZone: int
///pdEastNew: double*
///pdNorthNew: double*
///pdEastAcc: double*
///pdNorthAcc: double*
[System.Runtime.InteropServices.DllImportAttribute("<Unknown>", EntryPoint="TransProjPt", CallingConvention=System.Runtime.InteropServices.CallingConvention.StdCall)]
public static extern int TransProjPt([System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPStr)] System.Text.StringBuilder psGridFile, int lDirection, double dEasting, double dNorthing, int lZone, ref double pdEastNew, ref double pdNorthNew, ref double pdEastAcc, ref double pdNorthAcc) ;

感谢大家对此的帮助。

关于c# - 从 C# 调用 C DLL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5664737/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com