0

我正在开发一个(通用 Windows)c++/cx Directx 项目,该项目构建为 ac# UWP 项目中使用的 dll。

我正在使用 DirectX Toolkit 加载纹理。

我已经使用它从文件创建纹理,但现在我需要它从从 UWP 项目发送的字节数组创建纹理。但是当尝试使用 CreateWICTextureFromMemory() 时,HRESULT显示 0x88982F50:“找不到组件”

我能找到的关于这个问题的所有信息都表明字节不是正确的图像,但我在 UWP 项目中对其进行了测试,在那里我从 bingmaps 获得了字节数组(它是一个静态地图图像),我可以从这些图像中制作一个工作图像字节。

有人知道我做错了什么吗?

UWP c# 下载代码(获取字节):

private async Task DownloadTexture()
    {
        byte[] buffer = null;
        try
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(_url);
            WebResponse response = await request.GetResponseAsync();
            using (Stream stream = response.GetResponseStream())
            using (MemoryStream ms = new MemoryStream())
            {
                stream.CopyTo(ms);
                buffer = ms.ToArray();
            }
        }
        catch (Exception exception)
        {
            Logger.Error($"Could not Download Texture: {exception}");
        }

        _track3D.SetImage(out buffer[0], (ulong)buffer.Length);
    }

Directx C++ 代码(失败):

void Track3D::SetImage(uint8_t* ddsData, size_t ddsDataSize)
{
    HRESULT result = CreateWICTextureFromMemory(_d3dDevice.Get(), _d3dContext.Get(), ddsData, ddsDataSize, nullptr, _Terrain.ReleaseAndGetAddressOf());
    //here it goes wrong
    //TODO: use the texture
}

有效的 UWP C# 测试代码(显示图像):

private async void setImage(byte[] buffer) //test
    {
        try
        {
            BitmapImage bmpImage = new BitmapImage();
            using (InMemoryRandomAccessStream stream = new InMemoryRandomAccessStream())
            {
                await stream.WriteAsync(buffer.AsBuffer());
                stream.Seek(0);
                await bmpImage.SetSourceAsync(stream);
            }

            Image image = new Image();
            image.Source = bmpImage;

            ((Grid)Content).Children.Add(image);
        }
        catch (Exception exception)
        {
            Logger.Error($"{exception}");
        }
    }

编辑:

好的,结果缓冲区中的第一个字节在 C++ 代码中与从 UWP 发送时不同。当我在 C++ 代码中将第一个字节更改为正确的值(作为测试)时,纹理被正确创建。

这就提出了一个问题,为什么第一个字节的值会改变?(或者我做错了什么?)

根据要求,函数 setImage() 在 c# 中如下所示:

[MethodImpl]
public void __ITrack3DPublicNonVirtuals.SetImage(out byte ddsData, [In] ulong ddsDataSize);

(另外,我刚刚意识到参数名称中仍然包含“dds”,对此感到抱歉,将在我的代码中更改它,因为它具有误导性)

4

1 回答 1

1

0x88982F50: “找不到组件”</p>

WINCODEC_ERR_COMPONENTNOTFOUND每当 WIC 无法确定用于文件/二进制文件的格式编解码器时,就会发生这种情况。您的问题是您将数据从托管代码传输到本机代码是错误的。

您的互操作方法设置为:

[MethodImpl]
public void __ITrack3DPublicNonVirtuals.SetImage(out byte ddsData, [In] ulong ddsDataSize);

C++ 方法签名为:

void Track3D::SetImage(uint8_t* ddsData, size_t ddsDataSize)

由于out您的第一个参数是作为安全数组传递的,其长度在第一个元素中。

相反,您应该使用:

SetImage([In] byte ddsData, [In] ulong ddsDataSize); // C#

void Track3D::SetImage(const uint8_t* ddsData, size_t ddsDataSize); // C++.
于 2016-12-09T17:25:18.490 回答