希望这是一个无脑的简单问题,但它表明我缺乏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++端必须非常简单,我只是不知道它的语法.
我正在使用以下代码来调用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).
我究竟做错了什么?
快速的问题.我想知道我的应用程序正在执行的系统中是否存在DLL.
这可能在C#中吗?(以某种方式适用于所有Windows操作系统?)
对于DLL我的意思是一个非.NET经典DLL(一个Win32 DLL)
(基本上我想做一个检查,因为我使用的DLL可能会或可能不会出现在用户系统上,但我不希望应用程序在没有警告时崩溃:P)
我有一个带有清单的应用程序需要以管理员身份运行,但应用程序的一部分是使用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)
编辑
如果当前用户具有管理员权限,那么主进程将使用清单提升,在提升的代码中我想在用户非提升空间中运行命令,因为这似乎具有不同的环境变量等.我相信曾经线程启动它不能改变自己,它需要运行一个新的.
是否有一种方法可以从C#P/Invoke中调用用C编写并在Unix上构建的共享对象文件?
或者我需要使用Java或类似的东西?
希望这对于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签名中捕获这些语义?请在答案中包含示例呼叫站点.我目前的解决方案是使用两个签名.
我在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
我的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) 我想用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#或VB.Net中,知道视觉主题.theme文件的使用,我想在Windows中应用该视觉主题,而不依赖于其他应用程序,如RunDll32.exe,只需P/Invoking,但避免怪异/奇怪的事情,如打开个性化窗口,然后使用FindWindow函数关闭它,程序应该从平台调用自动化,而不是与其他窗口交互.
关于如何应用主题的这个问题之前在很多人面前被问过(包括我,通过注册表修改加上服务停止/恢复只能在Windows 7下运行的解决方案),我认为是时候让专家来说明我们了使用不涉及RunDll32.exe的WinAPI方法既不打开个性化窗口.
我不知道这会通过在注册表项设置一些值来完成HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\ThemeManager,然后发布/通过发送消息SendMessage或PostMessage或其它功能,或可能通知有关通过环境变化SendMessageTimeOut功能或SHChangeNotify或SystemParametersInfo或其他功能,因为在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)