我在visual studio中有两个c库A和B(DLL)。
库B依赖于库A公开的功能。一切都在没有警告和错误的情况下编译。
执行B.AddAt(...)
时,A.GetValue(...)
电话会触发访问冲突。
将A.GetValue(...)
替换为本地实现B.GetValueInternal(...)
时,一切正常。
请注意,B.GetValueInternal(...)
也会调用库A中定义的函数。
该函数从托管环境(C#)调用,如下所示:
[DllImport("B.dll", CallingConvention=CallingConvention.Cdecl)]
private static extern Container AddAt(IntPtr data, Container d, int x, uint size);
这就是c代码的外观:
A.DLL
A.H
#ifndef EXPORT_API
#define EXPORT_API __declspec(dllexport)
#endif
#ifndef A_H_INCLUDED
#define A_H_INCLUDED
typedef struct Container
{
float a;
float b;
float c;
} Container;
EXPORT_API Container GetValue(Container* data, int x, unsigned int size);
EXPORT_API int Clamp(int value, int min, int max);
#endif
A.C
#include "A.h"
EXPORT_API Container GetValue(Container* data, int x, unsigned int size)
{
unsigned int xx = Clamp(x, 0, size - 1);
return data[xx];
}
EXPORT_API int Clamp(int value, int min, int max)
{
return (value < min) ? min : (value > max) ? max : value;
}
B.DLL
B.h
#include "A.h"
#ifndef EXPORT_API
#define EXPORT_API __declspec(dllexport)
#endif
#ifndef B_H_INCLUDED
#define B_H_INCLUDED
Container GetValueInternal(Container* data, int x, unsigned int size);
EXPORT_API Container AddAt(Container* data, Container d, int x, unsigned int size);
#endif
B.c
#include "B.h"
Container GetValueInternal(Container* data, int x, unsigned int size)
{
unsigned int xx = Clamp(x, 0, size - 1);
return data[xx];
}
EXPORT_API Container AddAt(Container* data, Container d, int x, unsigned int size)
{
//Container v = GetValueInternal(data, x, size);// This works
Container v = GetValue(data, x, size);// This throws Access Violation
v.a += d.a;
v.b += d.b;
v.c += d.c;
return v;
}
什么可能导致这种行为?任何帮助将不胜感激!
更新: 调用代码如下所示:
[StructLayout(LayoutKind.Sequential)]
public struct Container
{
public float a;
public float b;
public float c;
}
Container d = ... //Some container
// input.NativePointer (IntPtr) points to a valid array of Containers
Container c = AddAt(input.NativePointer, d, 0, 4);