在C#项目中使用openh264库遇构建警告与运行错误求助
基于openh264的C#项目调用问题排查
项目配置
解决方案文件(h264.sln)
Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.0.31903.59 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "h264", "h264\h264.csproj", "{C9FA208E-5506-441B-9837-FB5469B950FA}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x86 = Debug|x86 Release|x86 = Release|x86 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {C9FA208E-5506-441B-9837-FB5469B950FA}.Debug|x86.ActiveCfg = Debug|x86 {C9FA208E-5506-441B-9837-FB5469B950FA}.Debug|x86.Build.0 = Debug|x86 {C9FA208E-5506-441B-9837-FB5469B950FA}.Release|x86.ActiveCfg = Release|x86 {C9FA208E-5506-441B-9837-FB5469B950FA}.Release|x86.Build.0 = Release|x86 EndGlobalSection EndGlobal
项目文件(h264.csproj)
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>net7.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable> </PropertyGroup> <ItemGroup> <Reference Include="openh264"> <HintPath>openh264-2.3.1-win32.dll</HintPath> </Reference> </ItemGroup> </Project>
Program.cs文件
using System.Runtime.InteropServices; public class h264Demo { [DllImport("openh264-2.3.1-win32.dll", CallingConvention = CallingConvention.Cdecl)] public static extern int WelsCreateSVCEncoder(); public static void Main() { Console.WriteLine("Hello h264 demo"); int result = WelsCreateSVCEncoder(); Console.WriteLine("Result is: {0}",result); } }
问题现象
- 构建项目时触发MSB3246警告:提示PE镜像无元数据
- 运行生成的可执行文件时触发0xC0000005致命错误(内存访问违规)
- 使用第三方封装库Openh264Lib.net可正常调用同版本openh264官方二进制文件
问题原因
- MSB3246警告根源:错误地将原生C++ DLL当作.NET程序集添加
<Reference>引用,原生DLL不包含.NET元数据,因此触发警告。 - 0xC0000005错误根源:
WelsCreateSVCEncoder函数签名声明错误。该函数实际返回ISVCEncoder*类型指针(C++中表示编码器实例),代码中用int接收,类型不匹配导致内存访问违规。
解决方案
1. 修正DLL引用方式
移除项目中的<Reference>节点,改用<None>元素将原生DLL复制到输出目录,确保运行时能找到DLL:
修改后的项目文件:
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>net7.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable> <!-- 确保平台与DLL一致 --> <PlatformTarget>x86</PlatformTarget> </PropertyGroup> <ItemGroup> <None Include="openh264-2.3.1-win32.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </None> </ItemGroup> </Project>
2. 修正函数签名
将WelsCreateSVCEncoder的返回类型改为IntPtr(对应C++的指针类型),正确声明如下:
修改后的Program.cs:
using System.Runtime.InteropServices; public class h264Demo { [DllImport("openh264-2.3.1-win32.dll", CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr WelsCreateSVCEncoder(); public static void Main() { Console.WriteLine("Hello h264 demo"); IntPtr encoderPtr = WelsCreateSVCEncoder(); Console.WriteLine("Encoder pointer address: 0x{0:X}", encoderPtr.ToInt64()); // 后续可通过指针调用其他openh264 API,例如释放编码器 if (encoderPtr != IntPtr.Zero) { [DllImport("openh264-2.3.1-win32.dll", CallingConvention = CallingConvention.Cdecl)] static extern void WelsDestroySVCEncoder(IntPtr encoder); WelsDestroySVCEncoder(encoderPtr); } } }
3. 验证平台一致性
确保项目的PlatformTarget设置为x86(与openh264-2.3.1-win32.dll的平台匹配),避免因32/64位不匹配导致的加载错误。
内容的提问来源于stack exchange,提问作者msmechanized
相关产品推荐
相关产品推荐

