标签: pinvoke

正确使用P/Invoke

我需要从c#调用外部dll.这是标题定义:

enum WatchMode { 
   WATCH_MODE_SYSTEM = 0,          
   WATCH_MODE_APPLICATION  = 1 };  

LONG ADS_API WDT_GetMode ( LONG i_hHandle, WatchMode * o_pWatchMode );
Run Code Online (Sandbox Code Playgroud)

我在C#中添加了枚举和调用:

public enum WatchMode
{
    WATCH_MODE_SYSTEM = 0,
    WATCH_MODE_APPLICATION = 1       
}
[DllImport("AdsWatchdog.dll")]
internal static extern long WDT_GetMode(long hHandle, ref WatchMode watchmode);
Run Code Online (Sandbox Code Playgroud)

这会生成AccessViolationException.我知道dll正在"工作",因为我还添加了一个调用GetHandle,返回hHandle上面提到的.我试图将参数更改为int(ref int watchmode)但得到相同的错误.没有人知道我怎么能拨打上述电话吗?

c# windows pinvoke interop

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

PInvoke CreateDesktop

我试图通过传递标志来通过子进程继承桌面的PInvoke CreateDesktop.声明如下:

[DllImport("user32", EntryPoint = "CreateDesktopW", CharSet = CharSet.Unicode, SetLastError = true)]
        public static extern IntPtr CreateDesktop(string lpszDesktop, IntPtr lpszDevice, IntPtr pDevmode, int dwFlags,
                                                  int dwDesiredAccess, [MarshalAs(UnmanagedType.LPStruct)] SECURITY_ATTRIBUTES lpsa);

        [StructLayout(LayoutKind.Sequential)]
        public struct SECURITY_ATTRIBUTES
        {
            public int nLength;
            public IntPtr lpSecurityDescriptor;
            public int bInheritHandle;
        }
Run Code Online (Sandbox Code Playgroud)

我用它如下:

Win32.SECURITY_ATTRIBUTES sa = new Win32.SECURITY_ATTRIBUTES();
            sa.nLength = Marshal.SizeOf(sa);
            sa.bInheritHandle = 1;
            testDesktopHandle = Win32.CreateDesktop(name, IntPtr.Zero, IntPtr.Zero, 0, Win32.GENERIC_ALL, sa);
Run Code Online (Sandbox Code Playgroud)

不幸的是,它不起作用,我收到以下错误:

System.Runtime.InteropServices.MarshalDirectiveException: Cannot marshal 'parameter #6': Invalid managed/unmanaged type combination (this value type must be paired …
Run Code Online (Sandbox Code Playgroud)

.net c# pinvoke interop

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

错误CS0133:将函数的结果赋值给C#.net中的const

尝试整理范围并避免可能多次调用RegisterWindowMessage.
目前有一个类使用以下成员一次

[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern int RegisterWindowMessage(string lpString);

private int m_message = RegisterWindowMessage("MY_MSG"); 
Run Code Online (Sandbox Code Playgroud)

由于我们只有一个实例,这似乎没问题,但认为使用它会更整洁.根据我的基本C#理解,这应该调用RegisterWindowMessage并将结果分配给int并且不允许它更改.

private const int message = RegisterWindowMessage("MY_MSG"); 
Run Code Online (Sandbox Code Playgroud)

但试图这样做会导致a

error CS0133: The expression being assigned to 'someclass.messageEvent' must be constant
Run Code Online (Sandbox Code Playgroud)

所以现在我很困惑,这是否意味着函数被分配并且每次调用之前都m_message被调用过,是否还有其他缺失?

c# syntax pinvoke

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

为什么这个Explicit P/Invoke不起作用?

以下.net到本机C代码不起作用,任何想法

extern "C" {
   TRADITIONALDLL_API int TestStrRef( __inout char* c)    {
   int rc = strlen(c);
   std::cout << "the input to TestStrRef is: >>" << c << "<<" ;
   c = "This is from the C code ";
   return rc;
   }
 }

 [DllImport("MyDll.dll", SetLastError = true)]
 static extern int TestStrRef([MarshalAs(UnmanagedType.LPStr)] ref string s);
 String abc = "InOut string";
 TestStrRef(ref abc);
Run Code Online (Sandbox Code Playgroud)

此时Console.WriteLine(abc)应该打印"这是来自C代码"但是没有,任何关于什么错误的想法?

仅供参考 - 我有另一个不使用ref类型字符串的测试函数,它工作得很好

c# c++ pinvoke visual-studio-2008 visual-c++

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

c ++中的字符串?

我的问题是,我在DLL中有一些函数,其中一些函数是例如:

#include <string>
using namespace std;
extern "C" __declspec(dllexport) string __cdecl encryption(string s)
{
 return s;
}
Run Code Online (Sandbox Code Playgroud)

每当我尝试从C#调用此函数时,以下是使用的代码:

[DllImport("Packer.dll", EntryPoint = "encryption")]
static extern string encryption(string s);
Run Code Online (Sandbox Code Playgroud)

我收到一个错误:调用PInvoke函数'Packer'使堆栈失衡.这很可能是因为托管PInvoke签名与非托管目标签名不匹配.检查PInvoke签名的调用约定和参数是否与目标非托管签名匹配.

我猜我得到这个错误,因为我没有正确的功能声明任何人都可以指导我如何解决这个问题,提前谢谢

c# c++ string pinvoke

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

Pinvoke vs ManagedCode

我想知道哪个更好地将C++代码转换为C#或从C#app中进行Pinvoking

这在性能和内存等方面会更好

.net c# c++ pinvoke

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

Dumpbin显示奇怪的方法名称(在MS Visual C++中生成导出功能)

我在VS中创建了新的Win32项目,并为此目的选择了动态库(*.dll).

我在主文件中定义了一些导出函数:

__declspec(dllexport)
int TestCall(void)
{
    int value = 4 / 2;
    std::cout << typeid(value).name() << std::endl;
    return value;
}

__declspec(dllexport)
void SwapMe(int *first, int *second)
{
    int tmp = *first;
    *first = *second;
    *second = tmp;
}
Run Code Online (Sandbox Code Playgroud)

当我看到dumpin/exports时,我得到了:

ordinal hint RVA      name

      1    0 00001010 ?SwapMe@@YAXPEAH0@Z
      2    1 00001270 ?TestCall@@YAHXZ
Run Code Online (Sandbox Code Playgroud)

我正在调用C#这样的版本:

[DllImport(@"lib1.dll", EntryPoint = "?TestCall@@YAHXZ",
CallingConvention = CallingConvention.Cdecl)]
static extern int TestCall();
Run Code Online (Sandbox Code Playgroud)

这不是使用导出方法的正确形式.我在C++ DLL项目中为导出方法生成这样的名称失败了吗?

dll pinvoke cdecl dllexport dumpbin

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

C#unsafe type - > char*[],在char数组上获取指针

有:

[DllImport("OpenAL32.dll")]
static extern void alcOpenDevice(char*[] devicename);
Run Code Online (Sandbox Code Playgroud)

想把这个名字发送给像smth那样的函数:

char[] data = "Hello!".ToCharArray();
char*[] txt = &data;
Run Code Online (Sandbox Code Playgroud)

但得到错误:

  • 无法隐式转换char[] *char * []

    (有趣的错误,因为C#编译器拒绝char[] *在/ unsafe模式中定义:))

  • 不能获取地址,获取大小,或声明指向托管类型的指针(char[])

PS
何时char成为管理?这是一个结构,不是吗?

public struct Char : IComparable, IConvertible, IComparable<char>, IEquatable<char>
Run Code Online (Sandbox Code Playgroud)

虽然编译器显示有关声明指向托管类型(char[])的指针的信息.我只能建议当类型是一个数组时,CLR可能会像管理类型一样呈现它,但听起来非常疯狂.

c# arrays pinvoke pointers unsafe

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

Getfield.SetValue不起作用

在我正在研究的项目中,我偶然发现了这个问题:

我想创建一个类"ApiID"的实例.我从Reflector获得了代码,因为你可以看到.dll(不是我的Project)导入来自ummanaged代码,我无权访问.

    [StructLayout(LayoutKind.Sequential, Size=0x10), CLSCompliant(false), NativeCppClass, DebugInfoInPDB, MiscellaneousBits(0x40)]
public struct ApiId
{
    private long <alignment member>;
    public static unsafe void <MarshalCopy>(ApiId* idPtr1, ApiId* idPtr2)
    {
        ApiId.{ctor}(idPtr1, (ApiId modopt(IsConst)* modopt(IsImplicitlyDereferenced)) idPtr2);
    }

    public static unsafe void <MarshalDestroy>(ApiId* idPtr1)
    {
        ApiId.{dtor}(idPtr1);
    }
}
Run Code Online (Sandbox Code Playgroud)

我的C#-Code看起来像这样:

var _apiId = new ApiId();
long vlue = 0x0000000041403070;
typeof(ApiId).GetField("<alignment member>", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(_apiId, vlue);
Run Code Online (Sandbox Code Playgroud)

该代码成功运行,但是Field不会改变并保持0 ...我做错了什么?问候

c# reflection pinvoke

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

.NET框架低级API如何工作?

我一直面临的一个问题是.NET Framework类库的实现.

我知道一些原始实现的方法:

例如 :

MessageBox.Show("...");
Run Code Online (Sandbox Code Playgroud)

据我所知,这个方法必须使用P/Invoke来调用Win32 API.

但是像这样:

System.Convert.ToInt32(mystr);
Run Code Online (Sandbox Code Playgroud)

我实际上不知道它是如何工作的,因为在纯C#中不可能在int和string之间进行转换.(你可以在不使用该方法的情况下做同样的事情吗?实际上我不知道).

最后,如果您知道答案,请在第二个例子中为我澄清这些概念.

.net c# pinvoke fcl

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