0x88982F50: "The component cannot be found" 使用 DirectXTK 的 CreateWICTextureFromMemory() 时

0x88982F50: "The component cannot be found" When using DirectXTK's CreateWICTextureFromMemory()

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

我正在使用 DirectX 工具包加载纹理。

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

我能找到的关于这个问题的所有信息都表明字节不是正确的图像,但我在 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',抱歉,我会在我的代码中更改它,因为它具有误导性)

0x88982F50: “The component cannot be found”

这是 WINCODEC_ERR_COMPONENTNOTFOUND,只要 WIC 无法确定 file/binary 使用哪种格式编解码器,就会发生这种情况。您的问题是您将数据从托管代码传输到本机代码是错误的。

您的互操作方法设置为:

[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++.