C#DllImport:调用vkCreateInstance时的AccessViolationException

时间:2016-04-16 13:56:29

标签: c# dllimport access-violation out vulkan

我试图用C#创建一个Vulkan包装器,但是当我调用一个函数时我遇到了一些问题。我重写了vulkan.h标题如下:

public static class Vk {
    [StructLayout(LayoutKind.Sequential)] public class Instance { }

    public enum Result {
        ...
    }
    public enum StructureType {
        ...
    }

    [StructLayout(LayoutKind.Sequential)] public class ApplicationInfo {
        public StructureType sType;
        public IntPtr pNext;
        public string pApplicationName;
        public uint applicationVersion;
        public string pEngineName;
        public uint engineVersion;
        public uint apiVersion;
    }

    [StructLayout(LayoutKind.Sequential)] public class InstanceCreateInfo {
        public StructureType sType;
        public IntPtr pNext;
        public uint flags_VkInstanceCreateFlags;
        public ApplicationInfo pApplicationInfo;
        public uint enabledLayerCount;
        public string[] ppEnabledLayerNames;
        public uint enabledExtensionCount;
        public string[] ppEnabledExtensionNames;
    }

    [DllImport("vulkan-1.dll", EntryPoint = "vkCreateInstance")]
    public extern static Result CreateInstance(
        InstanceCreateInfo pCreateInfo,
        IntPtr AllocationCallbacks_pAllocator,
        out IntPtr pInstance_Instance);
}

此功能的C中的原始声明是

VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance(
    const VkInstanceCreateInfo*                 pCreateInfo,
    const VkAllocationCallbacks*                pAllocator,
    VkInstance*                                 pInstance);

现在当我打电话给我的功能时,我这样做:

Vk.InstanceCreateInfo instance_create_info = new Vk.InstanceCreateInfo();
...

IntPtr hinstance;
Vk.Result result = Vk.CreateInstance(instance_create_info, IntPtr.Zero, out hinstance);   <-- error AccessViolationException

我不明白我的问题在哪里,因为它似乎是一个有效的解决方案:StackOverflow : AccessViolationException when calling vkEnumeratePhysicalDevices via pInvoke from c#

我尝试使用

初始化 IntPtr hinstance
Marshal.AllocHGlobal(Marshal.SizeOf<Vk.Instance>());  

我也尝试过&#34;转换&#34;我的instance_create_info到 Marshal.StructureToPtr(...); 的另一个IntPtr,我试图通过ref关键字传递 instance_create_info 实例。显然,没有任何效果。

有什么想法吗?

编辑:

本机函数的用法如下:

//Definition
typedef struct VkApplicationInfo {
    VkStructureType    sType;
    const void*        pNext;
    const char*        pApplicationName;
    uint32_t           applicationVersion;
    const char*        pEngineName;
    uint32_t           engineVersion;
    uint32_t           apiVersion;
} VkApplicationInfo;`
typedef struct VkInstanceCreateInfo {
    VkStructureType             sType;
    const void*                 pNext;
    VkInstanceCreateFlags       flags;
    const VkApplicationInfo*    pApplicationInfo;
    uint32_t                    enabledLayerCount;
    const char* const*          ppEnabledLayerNames;
    uint32_t                    enabledExtensionCount;
    const char* const*          ppEnabledExtensionNames;
} VkInstanceCreateInfo;

#define VK_DEFINE_HANDLE(object) typedef struct object##_T* object;
VK_DEFINE_HANDLE(VkInstance)

//Code
VkApplicationInfo application_info{};
    application_info.sType                  = VK_STRUCTURE_TYPE_APPLICATION_INFO;
    application_info.apiVersion             = VK_API_VERSION;
    application_info.applicationVersion     = VK_MAKE_VERSION( 1, 0, 0 );
    application_info.pApplicationName       = "";
    application_info.engineVersion          = VK_MAKE_VERSION( 1, 0, 0 );
    application_info.pEngineName            = "";

VkInstanceCreateInfo instance_create_info{};
    instance_create_info.sType                      = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
    instance_create_info.pApplicationInfo           = &application_info;
    instance_create_info.enabledLayerCount          = 0
    instance_create_info.ppEnabledLayerNames        = nullptr
    instance_create_info.enabledExtensionCount      = 0
    instance_create_info.ppEnabledExtensionNames    = nullptr

VkInstance _instance = nullptr;
assert( !vkCreateInstance( &instance_create_info, nullptr, &_instance ) );

2 个答案:

答案 0 :(得分:1)

似乎你正在尝试做类似的事情this guy为c#做了一个包装器。对你有用。转到Source / SharpVulkan / Generated / Functions。

WebDriverWait wait = new WebDriverWait(driver, 15);
        wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//li[@class='logout']/a")));
        boolean isLogoutDisplayed = driver.findElement(By.xpath("//li[@class='logout']/a")).isDisplayed();
        System.out.println("Is Logout displayed: " + isLogoutDisplayed);

希望它有用:)

答案 1 :(得分:-1)

删除第三个参数的btnPlay.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (isPlaying == false) { isPlaying = true; btnPlay.setBackgroundResource(R.drawable.stop_play_button); playAudio(); } else { isPlaying = false; btnPlay.setBackgroundResource(R.drawable.play_button); stopAudio(); } } }); 关键字或将其声明为相应的结构。