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++.
我正在开发一个(通用 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++.