标签: pinvoke

将函数从C++ dll导出到C#P/Invoke

我已经构建了一个C++ DLL,我想用C#代码调用它.我可以调用一个函数,但是当C#代码尝试加载dll时,另一个抛出异常.

标题看起来像这样:

extern "C" __declspec(dllexport) BOOL Install();
extern "C" __declspec(dllexport) BOOL PPPConnect();
Run Code Online (Sandbox Code Playgroud)

这会产生一个带有轻微混乱的导出表的dll(名称字段中的foo = foo是什么意思?):

File Type: DLL

Section contains the following exports for PPPManager.dll

00000000 characteristics
499F44F0 time date stamp Fri Feb 20 16:04:00 2009
    0.00 version
       1 ordinal base
       2 number of functions
       2 number of names

ordinal hint RVA      name

      1    0 000078E4 Install = Install
      2    1 000079DC PPPConnect = PPPConnect
Run Code Online (Sandbox Code Playgroud)

我的P/Invoke声明如下所示:

[DllImport("PPPManager.dll")]
private static extern bool Install();

[DllImport("PPPManager.dll")]
private static extern bool PPPConnect();
Run Code Online (Sandbox Code Playgroud)

对Install的调用没有异常返回,但是当我调用PPPConnect时,我得到一个MissingMethodException …

c# c++ dll pinvoke dllimport

8
推荐指数
1
解决办法
2万
查看次数

如何获取最后一个错误(WSAGetLastError)?

如何WSAGetLastError()从WinAPI 调用,以便获得有效的文本错误?

.net c# error-handling pinvoke winapi

8
推荐指数
2
解决办法
1万
查看次数

如何设置C++函数以便p/invoke可以使用它?

希望这是一个无脑的简单问题,但它表明我缺乏C++专业知识.我是一名C#程序员,过去我和其他人的C++/C dll一起完成了P/Invoke的大量工作.但是,这次我决定自己编写一个包装器C++ DLL(非托管),然后从C#调用我的包装器dll.

我遇到的问题是我无法定义可以通过p/invoke找到的C++函数.我不知道这是什么语法,但这是我到目前为止所做的:

extern bool __cdecl TestFunc()
{
  return true;
}
Run Code Online (Sandbox Code Playgroud)

最初我只是这个,但它也没有用:

bool TestFunc()
{
  return true;
}
Run Code Online (Sandbox Code Playgroud)

然后在C#方面,我有:

    public const string InterfaceLibrary = @"Plugins\TestDLL.dll";

    [DllImport( InterfaceLibrary, CallingConvention = CallingConvention.Cdecl,
        EntryPoint = "TestFunc" ), SuppressUnmanagedCodeSecurity]
    internal static extern bool TestFunc();
Run Code Online (Sandbox Code Playgroud)

所有东西都编译,但是当我执行这个C#p/invoke调用时,我得到一个System.EntryPointNotFoundException:无法在DLL'Plugins\TestDLL.dll'中找到名为'TestFunc'的入口点.

当然,这在C++端必须非常简单,我只是不知道它的语法.

c# c++ pinvoke dllimport extern

8
推荐指数
2
解决办法
3919
查看次数

在C#中使用TaskDialog时的EntryPointNotFoundException

我正在使用以下代码来调用TaskDialog.

    [DllImport("ComCtl32", CharSet = CharSet.Unicode, PreserveSig = false)]
    internal static extern void TaskDialogIndirect(
        [In] ref TASKDIALOGCONFIG pTaskConfig,
        [Out] out int pnButton,
        [Out] out int pnRadioButton,
        [Out] out bool pfVerificationFlagChecked);
Run Code Online (Sandbox Code Playgroud)

但是,我得到异常"无法在DLL'ComCtl32'中找到名为'TaskDialogIndirect'的入口点."

我拿了这个代码.我使用的是Windows 7 x64(RC).

我究竟做错了什么?

c# pinvoke taskdialog windows-7

8
推荐指数
1
解决办法
3321
查看次数

如何使用.net更改Windows2k8的时区设置

我已经尝试用c#代码改变我的系统的时区几天了,而我正在尝试的任何东西都没有多大意义或工作.我开始尝试使用我在其他问题上看到的SetTimeZoneInformation的PInvoke语法.

[DllImport("kernel32.dll", CharSet = CharSet.Auto)] private static extern bool
SetTimeZoneInformation([In] ref TimeZoneInformation lpTimeZoneInformation);
Run Code Online (Sandbox Code Playgroud)

我正在研究如何创建TimeZoneInformation结构并因为我的系统显然具有动态DST系统而感到困惑.事实证明,自从微软Vista添加了一种处理时区的新方法以来.您现在必须使用SetDynamicTimeZoneInformation

[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
private static extern bool SetDynamicTimeZoneInformation([In] ref DynamicTimeZoneInformation lpTimeZoneInformation);
Run Code Online (Sandbox Code Playgroud)

我在msdn上搜索了这个API的帮助,发现了一些问题,"应用程序必须具有SE_TIME_ZONE_NAME特权才能使此功能成功." 最终我发现这个页面看起来像是一个很好的代码来完成这个.问题是它不起作用.

这是我的非工作代码:

[StructLayout(LayoutKind.Sequential)]
public struct LUID
{
    public int LowPart;
    public int HighPart;
}

[StructLayout(LayoutKind.Sequential)]
public struct TOKEN_PRIVILEGES
{
    public LUID Luid;
    public UInt32 Attributes;
    public UInt32 PrivilegeCount;
}

[StructLayoutAttribute(LayoutKind.Sequential)]
public struct SystemTime
{
    public ushort Year;
    public ushort Month;
    public ushort DayOfWeek;
    public ushort Day;
    public ushort Hour;
    public ushort …
Run Code Online (Sandbox Code Playgroud)

.net c# pinvoke timezone

8
推荐指数
2
解决办法
4837
查看次数

为什么.NET程序能够在损坏的堆栈中存活?(当使用错误的调用约定时)

在VS2010中,如果使用错误的调用约定调用函数,则托管调试助手将为您提供pInvokeStackImbalance异常(pInvokeStackImbalance MDA),这通常是因为在调用C库时未指定CallingConvention = Cdecl.比如你写的

[DllImport("some_c_lib.dll")]
static extern void my_c_function(int arg1, int arg2);
Run Code Online (Sandbox Code Playgroud)

代替

[DllImport("some_c_lib.dll", CallingConvention=CallingConvention.Cdecl)]
static extern void my_c_function(int arg1, int arg2);
Run Code Online (Sandbox Code Playgroud)

因此获得了StdCall调用约定而不是Cdelc.

如果你回答这个问题,你已经知道了这个差异,但是对于这个线程的其他访问者:StdCall意味着被调用者清除堆栈中的参数,而Cdecl意味着调用者清理堆栈.

因此,如果您的C代码中的调用约定错误,则您的堆栈不会被清理并且程序崩溃.

但是,即使.NET程序使用StdCall进行Cdecl功能,.NET程序似乎也不会崩溃.默认情况下,VS2008上没有启用堆栈不平衡检查,因此一些VS2008项目使用了他们的作者不知道的错误调用约定.我刚尝试过GnuMpDotNet,即使缺少Cdelc声明,样本运行也很好.X-MPIR也是如此.

它们都在调试模式下抛出pInvokeStackImbalance MDA异常,但在发布模式下不会崩溃.为什么是这样?.NET VM是否将所有对本机代码的调用包装起来并在之后恢复堆栈本身?如果是这样,为什么还要使用CallingConvention属性呢?

.net pinvoke dllimport

8
推荐指数
1
解决办法
1133
查看次数

从.NET中的API调用Java方法

我在jar文件中有一个Java API,其中包含一些来自其他jar文件的依赖项.

有没有办法从这个API调用一个特定的方法,比如使用.NET的PInvoke?

谢谢.

c# java pinvoke

8
推荐指数
1
解决办法
2万
查看次数

用于GetLogicalProcessorInformation函数的PInvoke

我想通过c#/ PInvoke调用GetLogicalProcessorInformation函数,但是我坚持使用SYSTEM_LOGICAL_PROCESSOR_INFORMATIONstruct和CACHE_DESCRIPTORstruct.

我该如何定义这些结构以便正确使用?

主要表现在:
1.SYSTEM_LOGICAL_PROCESSOR_INFORMATION有工会在其定义
2. SYSTEM_LOGICAL_PROCESSOR_INFORMATION具有ULONGLONG在其定义
3. CACHE_DESCRIPTOR具有WORDDWORD在它的定义.

你能帮我解决这些问题吗?

c# windows cpu pinvoke

8
推荐指数
2
解决办法
3693
查看次数

如何在CIL DLL中导出方法,以便本机程序可以调用它?

我已经审核了ECMA 335,我只找到了对该.export关键字的引用,该关键字看起来很有前景但文档很少.关于在C#中执行此操作,我在StackOverflow上发现了类似的问题.然而,到目前为止,这些都没有带给我任何有用的东西.

底线是:我有一个CIL DLL,我想从本机C++应用程序调用它的一些静态方法.

.net pinvoke cil

8
推荐指数
1
解决办法
1522
查看次数

如何在IL中表示固定

我想知道字段固定是如何用.Net的IL语言表达的,所以我看了一下示例代码:

struct S
{
    public fixed int buf[8];
}
S s = default(S);
public void MyMethod() {              
    fixed (int* ptr = s.buf){            
        *ptr = 2;        
    }
}
Run Code Online (Sandbox Code Playgroud)

这会生成IL:

.method private hidebysig instance void MyMethod () cil managed 
{
    // Method begins at RVA 0x2050
    // Code size 25 (0x19)
    .maxstack 2
    .locals init (
        [0] int32& pinned
    )

    IL_0000: ldarg.0              // Load argument 0 onto the stack
    IL_0001: ldflda valuetype C/S C::s // Push the address of field of object …
Run Code Online (Sandbox Code Playgroud)

c# pinvoke cil

8
推荐指数
1
解决办法
203
查看次数

标签 统计

pinvoke ×10

c# ×8

.net ×4

dllimport ×3

c++ ×2

cil ×2

cpu ×1

dll ×1

error-handling ×1

extern ×1

java ×1

taskdialog ×1

timezone ×1

winapi ×1

windows ×1

windows-7 ×1