小编Asi*_*sik的帖子

未解决的外部尝试使用ffmpeg

我正在尝试使用ffmpeg中的一些函数,并且遇到了弹性链接器错误.这是我做的:

  • http://ffmpeg.zeranoe.com/builds/下载最新的32位"Dev"版本(即ffmpeg-20130418-git-ee94362-win32-dev)
  • 在Visual Studio 2012 Premium中创建了"常规 - 空"C++项目
  • 将[ffmpeg]/lib文件夹添加到链接器 - >输入 - >"其他库目录"
  • 添加了"swscale.lib; avutil.lib; avformat.lib; avdevice.lib; avcodec.lib;" 链接器 - >输入 - >"附加依赖项"
  • 在C++ - > General - > Additional Include Directories下添加了以下内容:
    • [FFMPEG] /包括
    • [FFMPEG] /包含/ libswscale
    • [FFMPEG] /包含/了libavformat

这是我的main.cpp:

#include "avformat.h"

int main()
{
    av_register_all();
} 
Run Code Online (Sandbox Code Playgroud)

这失败了:

错误LNK2019:函数_main中引用的未解析的外部符号"void __cdecl av_register_all(void)"(?av_register_all @@ YAXXZ)

我该如何解决这个错误?

c++ linker ffmpeg

6
推荐指数
1
解决办法
5737
查看次数

如何检测 WPF 控件何时被重绘?

我正在使用 D3DImage 显示一系列帧,这些帧依次渲染到同一个 Direct3D Surface 上。我目前的逻辑是:

  • 显示最后渲染的帧(即D3DImage.Lock()/AddDirtyRect()/Unlock())
  • 开始渲染下一帧
  • 等待下一帧准备好并显示它
  • 显示最后渲染的帧
  • ...

这种方法的问题在于,当我们在 D3DImage 上调用 Unlock() 后,图像实际上并未被复制,它只是计划在下一个 WPF 渲染时复制。因此,我们有可能在 WPF 有机会显示新帧之前在 Direct3D 表面上渲染它。最终结果是我们在显示屏上看到丢失的帧。

现在,我正在尝试使用单独的 Direct3D 纹理进行渲染,并在显示之前执行到“显示纹理”的复制,这提供了更好的结果,但会产生大量开销。最好能够知道 D3DImage 何时完成刷新并立即开始渲染下一帧。这可能吗,如果可以的话怎么办?或者你有更好的主意吗?

谢谢。

c# directx wpf

6
推荐指数
1
解决办法
1797
查看次数

在这种情况下,为什么未使用的构造函数会导致程序集依赖?

关于我想要理解的程序集依赖性有一个微妙的观点.我有一个项目,通过自定义包装器使用SharpDX,如下所示:

SharpDX.dll < - Wrapper.dll < - Project.dll

在Wrapper.dll中是一种类型:

public class D3DWrapperTypeA {
    //public D3DWrapperTypeA(SharpDX.Device device) {
    //    
    //}

    public D3DWrapperTypeA(IntPtr devicePointer) {
         SharpDX.Device device = new SharpDX.Device(devicePointer);
         // etc
    }
}
Run Code Online (Sandbox Code Playgroud)

在这个类中,如果我取消注释注释的构造函数,那么Project.dll必须引用SharpDX.dll,即使它不使用构造函数.

但是,我还有另一种包装类型:

public class WrapperTypeB {
    public SharpDX.Device GetDevice(int adapter) {
        // etc
    }

    public IntPtr GetDevicePointer(int adapter) {
        return GetDevice(adapter).NativePointer;
    }
}
Run Code Online (Sandbox Code Playgroud)

在这里,只要我实际上不使用返回SharpDX对象的GetDevice方法,Project.dll就不需要引用SharpDX.dll.

为什么即使是未使用的构造函数接受SharpDX类型的参数也会导致对SharpDX的依赖,而返回SharpDX类型参数的未使用的方法则不然?

.net c#

6
推荐指数
1
解决办法
200
查看次数

如何使用重载的显式转换运算符?

我有一个在C#中定义的类型,如下所示:

struct F {
    public static explicit operator F(long value) {}
    public static explicit operator long(F value) {}
    public static explicit operator F(double value) {}
    public static explicit operator double(F value) {}
    // more conversion operators
}
Run Code Online (Sandbox Code Playgroud)

在F#中,如果我想从长时间创建它,我找到的唯一方法是:

let l = F.op_Explicit 3L
Run Code Online (Sandbox Code Playgroud)

我尝试创建一个内联函数来使这更好:

let inline f a = F.op_Explicit a
Run Code Online (Sandbox Code Playgroud)

但这不编译.我也试过一个成员约束:

let inline f (x:^a) = (F: (static member op_Explicit : ^a -> F) x) 
Run Code Online (Sandbox Code Playgroud)

而这也不会编译.

是否可以定义一个函数或运算符来选择正确的过载?

另一方面,它在相反的方向上运行良好:

let f = someF |> int64 // calls the right conversion …
Run Code Online (Sandbox Code Playgroud)

f#

6
推荐指数
1
解决办法
302
查看次数

为什么没有对未使用的let绑定发出警告?

C#警告编译时常量的未使用变量:

static void Main(string[] args)
{
    var unused = "hey"; //CS0219 The variable 'unused' is assigned but its value is never used
    Console.WriteLine("Hello World!");
}
Run Code Online (Sandbox Code Playgroud)

但是F#编译器没有,即使编辑器现在确实选择了它:

在此输入图像描述

如果它不仅涵盖了编译时常量,而且涵盖了所有允许绑定,那么就会发现由于一个微不足道的错误导致的生产中的真正错误,类似于

let callApiXyz connectionInfo = async {
    let fullUrl = sprintf "%s..." connectionInfo.Url
    ...
    let! result = httpGet connectionInfo // fail, didn't use the modified url
    // Should have been:
    // let! result = httpGet { connectionInfo with Url = fullUrl }
    ...
}
Run Code Online (Sandbox Code Playgroud)

有没有理由没有这个(除了"功能不是免费的")?我认为这应该在功能第一语言中重要,其中表达式往往没有副作用,而不是C#.

f#

6
推荐指数
2
解决办法
219
查看次数

5
推荐指数
1
解决办法
5998
查看次数

编组结构数组与类

我想使用编组将本机结构读入 C# 类型。我对 Marshal 结构的方法是这样的:

T ReadObject<T>(BinaryReader br) {
    var bytes = br.ReadBytes(Marshal.SizeOf(typeof(T)));
    var handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
    try {
        return (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
    }
    finally {
        handle.Free();
    }
}
Run Code Online (Sandbox Code Playgroud)

现在这通常可以正常工作,问题出现在以下类型中:

[StructLayout(LayoutKind.Sequential, Pack=1)]
class SubData {
    public short A1;
    public short A2;
}

[StructLayout(LayoutKind.Sequential, Pack=1)]
class Data {
    public short Id;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst=3)]
    public SubData[] SubDatas;
}
Run Code Online (Sandbox Code Playgroud)

请注意,如果 SubData 是一个结构体这可以正常工作!但是如果 SubData 是一个类,它会导致 Marshal.PtrToStructure 抛出 FatalExecutionEngineError。我想坚持使用类,因为有时我的类型有默认值,结构不能有字段初始值设定项或默认构造函数,而且其中一些类型相当大。

谢谢您的帮助。

编辑:错误消息是“运行时遇到了致命错误。错误的地址是 0x6af99aec,在线程 0x348 上。错误代码是 0xc0000005。此错误可能是 CLR 中的错​​误或不安全或非用户代码的可验证部分。此错误的常见来源包括 COM-interop 或 PInvoke 的用户封送错误,这可能会破坏堆栈。”

.net c# interop native marshalling

5
推荐指数
1
解决办法
3608
查看次数

奇怪的InvokeRequired问题

我有一个带有TreeView控件的UserControl,名为mTreeView.我可以从多个不同的线程获取数据更新,这些更新会导致TreeView更新.为此,我设计了以下模式:所有数据更新事件处理程序必须获取锁,然后检查InvokeRequired; 如果是这样,请通过调用Invoke来完成工作.这是相关的代码:

  public partial class TreeViewControl : UserControl
  {  
    object mLock = new object();
    void LockAndInvoke(Control c, Action a)
    {
      lock (mLock)
      {
        if (c.InvokeRequired)
        {
          c.Invoke(a);
        }
        else
        {
          a();
        }
      }
    }

    public void DataChanged(object sender, NewDataEventArgs e)
    {
      LockAndInvoke(mTreeView, () =>
        {
          // get the data
          mTreeView.BeginUpdate();
          // perform update
          mTreeView.EndUpdate();
        });
    }    
  }
Run Code Online (Sandbox Code Playgroud)

我的问题是,有时,在启动时,我会在mTreeView.BeginUpdate()上得到一个InvalidOperationException,说mTreeView是从一个不同于它创建的线程更新的.我在调用堆栈中返回到我的LockAndInvoke,并且看,c.InvokeRequired是真的但是其他分支已被占用!就像在调用else分支后,在另一个线程上将InvokeRequired设置为true一样.

我的方法有什么问题,我该怎么做才能防止这种情况发生?

编辑:我的同事告诉我,问题是InvokeRequired是错误的,直到创建控件,所以这就是它在启动时发生的原因.但他不知道该怎么办.有任何想法吗?

c# multithreading winforms

5
推荐指数
1
解决办法
1615
查看次数

64位定点乘法错误

我正在C#中实现64位定点签名31.32数字类型long.到目前为止,添加和减法都很好.然而,乘法有一个我想要解决的烦人案例.

我当前的算法包括将每个操作数分成最高和最低有效32位,执行4次乘法到4个长度并添加这些长度的相关位.这是代码:

public static Fix64 operator *(Fix64 x, Fix64 y) {

    var xl = x.m_rawValue; // underlying long of x
    var yl = y.m_rawValue; // underlying long of y

    var xlow = xl & 0x00000000FFFFFFFF; // take the 32 lowest bits of x
    var xhigh = xl >> 32; // take the 32 highest bits of x
    var ylow = yl & 0x00000000FFFFFFFF; // take the 32 lowest bits of y
    var yhigh = yl >> 32; // …
Run Code Online (Sandbox Code Playgroud)

c# math binary fixed-point

5
推荐指数
1
解决办法
886
查看次数

这种gcroot的使用安全吗?

我需要使用C++/CLI中的非托管API.此API存储指向任意用户数据和一些回调的void指针.然后它最终调用那些回调,将用户数据作为void*传递.

到目前为止,我有一个本机类将其"this"指针作为用户数据传递,并使用该指针将API调用回此类,即:

static void __stdcall Callback(void* userData) {
    ((MyType*)userData)->Method();
}

class MyType {
public:
    MyType() { RegisterWithApi((void*)this, Callback); }
    void Method();
};
Run Code Online (Sandbox Code Playgroud)

我正在尝试使用托管类来翻译它.我发现gcroot类型可以用来在本机代码中安全地存储托管引用,所以我现在就是这样做的:

// This is called by the native API
static void __stdcall Callback(void* userData) {
    // Cast back to gcroot and call into managed code
    (*(gcroot<MyType^>*)userData)->Method();
}

ref class MyType {
    gcroot<MyType^>* m_self;
public:
    MyType() { 
        m_self = new gcroot<MyType^>;
        RegisterWithApi((void*)m_self, Callback);
    }
    ~MyType() { delete m_self; }
    // Method we want called by the native API
    void …
Run Code Online (Sandbox Code Playgroud)

.net c++ interop garbage-collection c++-cli

5
推荐指数
1
解决办法
4243
查看次数