首页 > 解决方案 > powershell调用具有结构类型参数的c ++ dll的导出函数

问题描述

struct foostruct
{
    int B;
    int A;
    int D;
};

int foofunc(foostruct foo)
{
    return foo.A;
}

我已经导出FooFunctest.dll 现在我正在尝试从 powershell 调用它

$source =  @"
public struct foostruct {
public int B;
public int A;
public int D;
}
"@
Add-Type -TypeDefinition $Source -IgnoreWarnings
$bar = New-Object foostruct
$bar.B = 1;
$bar.A = 2;
$bar.D = 3;

$MethodDefinition = @'

[DllImport("test.dll", CharSet = CharSet.Unicode, SetLastError = true)]

public static extern int foofunc(foostruct foo);

'@

$dll = Add-Type -MemberDefinition $MethodDefinition -Name 'dll' -PassThru -IgnoreWarnings

这会引发错误

The type or namespace name 'foostruct' could not be found (are you missing a using directive or an assembly reference?)

我尝试按照这里提到的移动fostruct内部的定义,但是当我使用下面的方法调用它时,我得到了错误。$MethodDefinitionUnable to cast object of type 'System.Object[,]' to type 'System.Object[]'

$Result = $dll::foofunc($bar)

标签: c++powershell

解决方案


The type or namespace name 'foostruct' could not be found (are you missing a using directive or an assembly reference?)使用两个单独的 s的原因Add-Type是它们在幕后创建了单独的程序集,而“MemberDefinition”程序集不知道“TypeDefinition”程序集,因此无法将foostruct类型解析为实现。

尝试 1 - 失败

Add-Type因此,让我们根据您链接到的答案将这两个声明移到一个“MemberDefinition”中:

$source = @"
public struct foostruct
{
    public int B;
    public int A;
    public int D;
}
[DllImport("test\\test\\x64\\Debug\\test.dll", CharSet=CharSet.Unicode, SetLastError=true)]
public static extern int foofunc(foostruct foo);
"@
Add-Type -MemberDefinition $Source -Name "dll";

$bar = New-Object foostruct
$bar.B = 1;
$bar.A = 2;
$bar.D = 3;

$dll::foofunc($bar);

运行这个对 来说很好Add-Type,但是尝试使用foostruct会给出这个错误:

New-Object : Cannot find type [foostruct]: verify that the assembly containing this type is loaded.
At C:\src\so\pinvoke\test.ps1:25 char:8
+ $bar = New-Object foostruct
+        ~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidType: (:) [New-Object], PSArgumentException
    + FullyQualifiedErrorId : TypeNotFound,Microsoft.PowerShell.Commands.NewObjectCommand

foostruct类型对 PowerShell 可见DllImport,但对 PowerShell 不可见 :-(

尝试 2 - 失败

好的,让我们尝试将其作为“TypeDefinition”Add-Type来代替:

$source = @"
public struct foostruct
{
    public int B;
    public int A;
    public int D;
}
[DllImport("test\\test\\x64\\Debug\\test.dll", CharSet=CharSet.Unicode, SetLastError=true)]
public static extern int foofunc(foostruct foo);
"@
Add-Type -TypeDefinition $Source;

$bar = New-Object foostruct
$bar.B = 1;
$bar.A = 2;
$bar.D = 3;

由于编译器期望包装在类Add-Type中的“浮动” ,这会产生编译错误:[DllImport]

Add-Type : c:\Users\Mike\AppData\Local\Temp\cchnscq4\cchnscq4.0.cs(14) : Expected class, delegate, enum, interface, or
struct
c:\Users\Mike\AppData\Local\Temp\cchnscq4\cchnscq4.0.cs(13) :     [DllImport("test\\test\\x64\\Debug\\test.dll",
CharSet=CharSet.Unicode, SetLastError=true)]
c:\Users\Mike\AppData\Local\Temp\cchnscq4\cchnscq4.0.cs(14) : >>>     public static extern int foofunc(foostruct foo);
c:\Users\Mike\AppData\Local\Temp\cchnscq4\cchnscq4.0.cs(15) :
At C:\src\so\pinvoke\test.ps1:22 char:1
+ Add-Type -TypeDefinition $Source;
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (Microsoft.Power...peCompilerError:AddTypeCompilerError) [Add-Type], Except
   ion
    + FullyQualifiedErrorId : SOURCE_CODE_ERROR,Microsoft.PowerShell.Commands.AddTypeCommand

尝试 3 - 成功

我们可以在上面$Source的“TypeDefinition”Add-Type版本中调整字符串以使编译器满意:

$source =  @"
using System.Runtime.InteropServices;

public struct foostruct
{
    public int B;
    public int A;
    public int D;
}

public static class NativeMethods
{

    [DllImport("test\\test\\x64\\Debug\\test.dll", CharSet=CharSet.Unicode, SetLastError=true)]
    public static extern int foofunc(foostruct foo);

}
"@
Add-Type -TypeDefinition $Source;

$bar = New-Object foostruct
$bar.B = 1;
$bar.A = 2;
$bar.D = 3;

[NativeMethods]::foofunc($bar);

请注意,foofunc它现在是该类的静态成员[NativeMethods]

版本的输出如下:

2

这基本上是$bar.AC++ 函数返回的值,所以一切似乎都按要求工作。

笔记

我无法重现您的Unable to cast object of type 'System.Object[,]' to type 'System.Object[]'错误,所以我无法真正解释这一点,但希望上面的答案可以帮助您解决问题......


推荐阅读