C - 调用外部函数

时间:2016-03-15 16:49:36

标签: c# c dll access-violation

我在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);

0 个答案:

没有答案