标签: pinvoke

如何设置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
查看次数

检查系统中是否存在DLL

快速的问题.我想知道我的应用程序正在执行的系统中是否存在DLL.

这可能在C#中吗?(以某种方式适用于所有Windows操作系统?)

对于DLL我的意思是一个非.NET经典DLL(一个Win32 DLL)

(基本上我想做一个检查,因为我使用的DLL可能会或可能不会出现在用户系统上,但我不希望应用程序在没有警告时崩溃:P)

c# windows dll pinvoke winapi

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

在另一个用户上下文中执行代码

我有一个带有清单的应用程序需要以管理员身份运行,但应用程序的一部分是使用WNetAddConnection2映射驱动器,我相信由于凭据等原因,它需要在普通用户上下文中运行.有没有办法执行此操作普通用户上下文中的一些代码,无需创建单独的进程.

编辑

从我的评论到目前为止,但它不起作用.我预计它不会因为我真的不明白我应该如何使用它.如果我打开一个新问题,也许最好?

class Program
{
    [DllImport("advapi32.DLL")]
    public static extern bool ImpersonateLoggedOnUser(IntPtr hToken);
    [DllImport("advapi32.DLL")]
    public static extern bool RevertToSelf();

    static void Main(string[] args)
    {
        IntPtr phToken = IntPtr.Zero;
        ImpersonateLoggedOnUser(phToken);
        MapDrives();
        RevertToSelf();
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑

如果当前用户具有管理员权限,那么主进程将使用清单提升,在提升的代码中我想在用户非提升空间中运行命令,因为这似乎具有不同的环境变量等.我相信曾经线程启动它不能改变自己,它需要运行一个新的.

.net c# pinvoke winapi uac

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

从c#调用UNIX和Linux共享对象文件.so

是否有一种方法可以从C#P/Invoke中调用用C编写并在Unix上构建的共享对象文件?

或者我需要使用Java或类似的东西?

c# linux mono pinvoke shared-libraries

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

如何在某些情况下需要空指针的P/Invoke签名中使用SafeHandle?

希望这对于SO来说并不是太模糊,但请考虑以下P/Invoke签名:

[DllImport("odbc32.dll", CharSet = CharSet.Unicode)]
internal static extern OdbcResult SQLAllocHandle(
    OdbcHandleType HandleType,
    IntPtr InputHandle,
    ref IntPtr OutputHandlePtr);
Run Code Online (Sandbox Code Playgroud)

我想重新设计此签名以使用SafeHandles,如下所示:

[DllImport("odbc32.dll", CharSet = CharSet.Unicode)]
internal static extern OdbcResult SQLAllocHandle(
    OdbcHandleType HandleType,
    MySafeHandle InputHandle,
    ref MySafeHandle OutputHandlePtr);
Run Code Online (Sandbox Code Playgroud)

但是,根据MSDN,当HandleType参数为SQL_HANDLE_ENV时,InputHandle参数必须为空指针,否则为非空指针.

如何在单个P/Invoke签名中捕获这些语义?请在答案中包含示例呼叫站点.我目前的解决方案是使用两个签名.

c# pinvoke dllimport cer

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

使用Windows 8/WinRT在Metro应用程序中进行PInvoke

我在Silverlight 5浏览器中有一个简单的FM Radio Tuner应用程序,它使用PInvoke从我的USB FM接收器调用来自Native C++ DLL的代码.此应用程序在带有Silverlight5的Windows 8中运行良好.

现在我正在尝试使用WinRT将其移植到Metro App.

从Silverlight迁移到XAML UI非常简单且运行良好.使用命名空间System.Runtime.InteropServices和DLLImport属性检测到PInvoke签名和属性.

问题是,当我运行应用程序并调用从使用在我的SL5的应用程序工作(即正常工作,甚至在Windows8中)的PInvoked本地DLL的任何方法,我有这样的例外:

System.DllNotFoundException was unhandled by user code
  Message=Unable to load DLL 'CarTFTFM.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)
  Source=metroradio
  TypeName=""
  StackTrace:
       at MetroRadio.FMRadio.HWInit2(Int32 port, Int32 initVolume)
       at MetroRadio.MediaService.InitializeRadio() in c:\Users\Gutemberg\Documents\Visual Studio 11\Projects\MetroRadio\MetroRadio\MediaService.cs:line 160
       at MetroRadio.MainPage.radio_Click(Object sender, RoutedEventArgs e) in c:\Users\Gutemberg\Documents\Visual Studio 11\Projects\MetroRadio\MetroRadio\MainPage.xaml.cs:line 43
  InnerException: 
Run Code Online (Sandbox Code Playgroud)

所以,我的问题是,这个PInvoke有什么问题?由于它在带有SL5应用程序的Windows8上运行良好,我没有看到任何与WinRT/Metro应用程序有问题的原因.

silverlight pinvoke microsoft-metro windows-8 windows-runtime

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

如何编组指向结构数组指针的指针?

我的C声明如下:

int myData(uint myHandle, tchar *dataName, long *Time, uint *maxData, DATASTRUCT **data);

typedef struct {
  byte Rel;
  __int64 Time;
  char Validated;
  unsigned char Data[1];
} DATASTRUCT ;
Run Code Online (Sandbox Code Playgroud)

我的C#声明如下:

[DllImport("myData.dll", EntryPoint = "myData")]
public static extern int myData(uint myHandle, [MarshalAs(UnmanagedType.LPTStr)] string dataName, out long Time, out uint maxData, ref DATASTRUCT[] data);

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct DATASTRUCT
{
    public sbyte Rel;
    public long Time;
    public byte Validated;
    public double Data;
}
Run Code Online (Sandbox Code Playgroud)

然后我调用托管函数如下:

string dataToShow = "description";
long Time;
uint maxData; …
Run Code Online (Sandbox Code Playgroud)

.net c# pinvoke interop marshalling

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

如何在c#(解组返回结构)中调用此c函数?

我想用c#interop从用c编写的dll中调用一个函数.我有头文件.看看这个:

enum CTMBeginTransactionError {
    CTM_BEGIN_TRX_SUCCESS = 0,
    CTM_BEGIN_TRX_ERROR_ALREADY_IN_PROGRESS,
    CTM_BEGIN_TRX_ERROR_NOT_CONNECTED
};

#pragma pack(push)
#pragma pack(1)
struct CTMBeginTransactionResult {
    char *                        szTransactionID;
    enum CTMBeginTransactionError error;
};

struct CTMBeginTransactionResult ctm_begin_customer_transaction(const char * szTransactionID);
Run Code Online (Sandbox Code Playgroud)

如何从c#调用ctm_begin_customer_transaction.const char*mapps很好用于字符串,但尽管有各种尝试(查看stackoverflow和其他站点),但我无法编组返回结构.如果我定义函数返回IntPtr它可以工作正常...

编辑 我将返回类型更改为IntPtr并使用:CTMBeginTransactionResult structure =(CTMBeginTransactionResult)Marshal.PtrToStructure(ptr,typeof(CTMBeginTransactionResult)); 但它抛出AccessViolationException

我也尝试过:

IntPtr ptr = Transactions.ctm_begin_customer_transaction("");
int size = 50;
byte[] byteArray = new byte[size];
Marshal.Copy(ptr, byteArray, 0, size);
string stringData = Encoding.ASCII.GetString(byteArray);
Run Code Online (Sandbox Code Playgroud)

stringData =="70e3589b-2de0-4d1e-978d-55e22225be95\0 \"\ 0\0\a\0\0\b\b?"此时."70e3589b-2de0-4d1e-978d-55e22225be95"是结构中的szTransactionID.枚举在哪里?它是下一个字节吗?

c# pinvoke interop unmarshalling

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

如何通过P/Invoking在Windows 8/8.1中以编程方式更改视觉主题?

C#VB.Net中,知道视觉主题.theme文件的使用,我想在Windows中应用该视觉主题,而不依赖于其他应用程序,如RunDll32.exe,只需P/Invoking,但避免怪异/奇怪的事情,如打开个性化窗口,然后使用FindWindow函数关闭它,程序应该从平台调用自动化,而不是与其他窗口交互.

关于如何应用主题的这个问题之前在很多人面前被问过(包括我,通过注册表修改加上服务停止/恢复只能在Windows 7下运行的解决方案),我认为是时候让专家来说明我们了使用不涉及RunDll32.exe的WinAPI方法既不打开个性化窗口.

我不知道这会通过在注册表项设置一些值来完成HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\ThemeManager,然后发布/通过发送消息SendMessagePostMessage或其它功能,或可能通知有关通过环境变化SendMessageTimeOut功能或SHChangeNotifySystemParametersInfo或其他功能,因为在uxtheme.dll库中似乎有什么对于这个任务有用,问题是什么功能以及用什么参数来应用视觉主题变化,有一些商业应用程序可以做到这一点,那么这是做它的步骤?,我尝试了所有这些功能但没有成功.


这是我过去为Windows 7做的解决方案,我记得这并不完美,因为对于某些主题,颜色没有正确应用,只有用户会话重新登录才能解决,以便在修改后正确影响更改:

Private Sub SetAeroTheme(ByVal themeFile As String,
                         Optional ByVal colorName As String = "NormalColor",
                         Optional ByVal sizeName As String = "NormalSize")

    Dim regKeyPath As String = "Software\Microsoft\Windows\CurrentVersion\ThemeManager"

    Using themeService As New ServiceController("Themes")

        If themeService.Status = ServiceControllerStatus.Running Then
            themeService.Stop()
            themeService.WaitForStatus(ServiceControllerStatus.Stopped)
        End If

        Using regKey As RegistryKey = Registry.CurrentUser.OpenSubKey(regKeyPath, …
Run Code Online (Sandbox Code Playgroud)

c# vb.net windows pinvoke winapi

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