如何使用来自 C# 的 C 回调
How to use a C callback from C#?
这是库秘密兔子代码(又名libsamplerate)的.NET包装器,在回调中调用src_callback_read时读取: 访问违规异常 - 试图读取或写入受保护的内存。
从 C 标头:
/* Opaque data type SRC_STATE. */
typedef struct SRC_STATE_tag SRC_STATE ;
typedef long (*src_callback_t) (void *cb_data, float **data) ;
SRC_STATE* src_callback_new (src_callback_t func, int converter_type, int channels, int *error, void* cb_data) ;
long src_callback_read (SRC_STATE *state, double src_ratio, long frames, float *
然后我创建了以下内容:
调用 C 库的 C++/CLI 类库:
public delegate long SRCCallback ( void *cb_data, float **data ) ;
static IntPtr CallbackNew ( SRCCallback ^func, RabbitConverter converter_type, int channels, int *error, void* cb_data )
{
src_callback_t* cb = ( src_callback_t* ) &func;
SRC_STATE* state = src_callback_new ( *cb, ( int ) converter_type, channels, error, cb_data );
IntPtr ptr = IntPtr ( state );
return ptr;
}
static long CallbackRead ( IntPtr src_state, double src_ratio, long frames , float * data )
{
void* toPointer = src_state.ToPointer();
SRC_STATE* state = ( SRC_STATE* ) toPointer;
long l = src_callback_read ( state, src_ratio, frames, data );
return l;
}
使用 C++/CLI 库的 C# 应用程序:
private static readonly unsafe SRCCallback _callback = target;
private static unsafe void Callback()
{
var input = GetSine(1000.0d, 44100, 1);
fixed (float* f = input)
{
RabbitError error = RabbitError.SRC_ERR_NO_ERROR;
var @void = Rabbit.CallbackNew(_callback, RabbitConverter.SRC_SINC_BEST_QUALITY, 1, (int*) (&error),
(void*) IntPtr.Zero);
var callbackRead = Rabbit.CallbackRead(@void , 1d, input.Length/2, f);
if (callbackRead != input.Length)
{
// throw new InvalidOperationException();
}
}
}
private static unsafe int target(void* cb_data, float** data)
{
return 9;
}
我已经使用以下方法修复了它:
[System::Runtime::InteropServices::UnmanagedFunctionPointerAttribute ( CallingConvention::Cdecl )]
public delegate long SRCCallback ( void *cb_data, float **data ) ;
static IntPtr CallbackNew ( SRCCallback ^ % func, RabbitConverter converter_type, int channels, int *error, void* cb_data ) { ... }
简而言之:现在它使用 C 调用约定和 C# ref 关键字。
相关文章:
- 如何在C++中使用非静态成员函数作为回调函数
- 如何使用C++对象的成员函数作为 C 样式回调?
- pcap_handler回调仅在使用 NPCAP v0.9991 时包含空数据包
- 如何使用 Node-addon-API 实现 node-nan 回调
- C++ 事件管理器的回调,使用 std::function 和 std:bind 以及派生类作为参数
- 使用带有闭包的 lambda 的回调
- 使用SWIG从C++回调到C#
- 如何使用从处理程序调度的最终回调将响应异步返回给调用方on_read?
- 如何使用软化工具包从 OPC UA 服务器异步读取操作回调中的数据值响应中获取 NodeId 详细信息
- Boost.Asio:不能使用 std::bind() 来指定回调
- 使用回调函数从构造函数调用虚拟/派生方法的替代方法?
- 我可以使用谷歌 v8 在回调函数中获取 JavaScript 函数C++源文本吗?
- 重写另一个方法 [C++] 使用的超类回调函数
- 更新 Visual Studio 2017,现在出现编译错误 C7510:"回调":使用依赖模板名称必须以 'template' 为前缀
- 在回调中使用函数时,C++未知重写说明符
- 如何定义与将 Lambda 与捕获作为回调一起使用兼容的函数指针
- Boost Asio和Co_await-与任何第三方回调一起使用
- 如何在本机回调中使用Cython CDEF类成员方法
- SQLite3_exec回调未使用c++中的INSERT语句调用
- 将函子/lambdas与C回调一起使用