将 C 风格的整数数组传递给 Ada 函数以检索数组中的第一个元素
Passing a C-styled integer array to an Ada function to retrieve the first element in the array
我正在 运行 一个尝试 link google 测试 ada95 进行单元测试的实验。我知道 ada 有 aunit 和 ahven,但这只是为了看看这是否可能并且超出了我的问题范围。我已经成功地能够使用基本数据类型执行简单的函数和过程。接下来我想尝试做的事情类似于以下内容:
这是 main.cpp 文件:
#include <stdio.h>
#include <gtest/gtest.h>
extern "C" {
int firstElement(int buffer[]);
}
TEST(tryTest, checkBuffer){
int buffer[10] = {10,1,6,4,3,2,1,3,4,6};
ASSERT_EQ(buffer[0],firstElement(buffer));
}
int main(int argc, char ** argv) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
为简单起见,我将只放置广告文件:
Lib_test.ads
with Interfaces.C;
with Interfaces.C.Pointers;
package Lib_Test is
function FirstElement(a: Interfaces.C.Pointers) return Interfaces.C.Int;
pragma Export(C,FirstElement,"firstElement");
end Lib_Test;
我知道在 c 中,您传递的是指向第一个元素的指针,而不是函数的整个数组。这就是为什么我尝试使用 Interfaces.C.Pointers 作为数据类型但出现以下错误
subtype mark required in this context
found "Pointers" declared at i-cpoint.ads:44
除了 char 数组,我还没有找到使用其他数组类型的好例子。有人可以告诉我如何将 Interfaces.C.Pointers 用于整数数组,甚至如何解决这个问题,我相信这只是我在函数参数中的数据类型。我希望能够访问 ada 函数中的 c 整数数组。
谢谢大家!
根据RM B.3 (70):
An Ada parameter of an array type with component type T, of any mode, is passed as a t* argument to a C function, where t is the C type corresponding to the Ada type T.
因此,不需要使用包 Interfaces.C.Pointers
。您可以只使用 Ada 数组类型。一个小例子:
main.cpp
#include <stdio.h>
#include <gtest/gtest.h>
extern "C" {
void testinit();
void testfinal();
int firstElement(int *buffer);
}
class MyTest : public ::testing::Test {
protected:
MyTest() {
testinit(); // Initialize the Ada library
}
~MyTest() override {
testfinal(); // Finalize the Ada library
}
};
TEST_F(MyTest, CheckBuffer) {
int buffer[10] = {10,1,6,4,3,2,1,3,4,6};
ASSERT_EQ(buffer[0], firstElement(buffer));
}
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
test.gpr
with "libtest";
project Test is
for Source_Dirs use ("src");
for Object_Dir use "obj";
for Main use ("main.cpp");
for Languages use ("C++");
package Compiler is
for Switches ("c++") use ("-I/usr/src/googletest/googletest/include");
end Compiler;
package Linker is
for Switches ("c++") use ("-lgtest", "-lgtest_main", "-pthread", "-ltest");
end Linker;
end Test;
lib_test.ads
with Interfaces.C;
package Lib_Test is
package C renames Interfaces.C;
type Seq is array (0 .. 9) of C.Int;
function First_Element (A : Seq) return C.Int;
pragma Export (C, First_Element, "firstElement");
end Lib_Test;
lib_test.adb
package body Lib_Test is
-------------------
-- First_Element --
-------------------
function First_Element (A : Seq) return C.Int is
begin
return A (A'First);
end First_Element;
end Lib_Test;
libtest.gpr
library project Libtest is
for Library_Kind use "dynamic";
for Library_Name use "test";
for Library_Interface use ("lib_test");
for Library_Auto_Init use "False";
for Library_Dir use "lib";
for Object_Dir use "obj";
for Source_Dirs use ("src");
end Libtest;
输出
$ ./obj/main
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from MyTest
[ RUN ] MyTest.CheckBuffer
[ OK ] MyTest.CheckBuffer (0 ms)
[----------] 1 test from MyTest (0 ms total)
[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (0 ms total)
[ PASSED ] 1 test.
除了@DeeDee 的完整回答之外:如果您真的只想要第一个元素,因为您收到一个指向 int 的指针,以下任何 Ada 声明都应该有效(未经测试!!) :
function First_Element (A : in out C.int) return C.Int;
-- An in/out argument exported with C convention should
-- use a pointer underneath.
function First_Element (A : aliased C.int) return C.Int;
-- Not sure this is already in Ada 95. By marking the
-- argument aliased, it's passed by reference.
function First_Element (A : access C.int) return C.Int;
-- Explicit pointer. I don't like this one (too low level),
-- but it's a possibility.
摆脱你的问题的关键思想是使用实际的指针类型,然后确保使用某种传递引用模式。
我正在 运行 一个尝试 link google 测试 ada95 进行单元测试的实验。我知道 ada 有 aunit 和 ahven,但这只是为了看看这是否可能并且超出了我的问题范围。我已经成功地能够使用基本数据类型执行简单的函数和过程。接下来我想尝试做的事情类似于以下内容:
这是 main.cpp 文件:
#include <stdio.h>
#include <gtest/gtest.h>
extern "C" {
int firstElement(int buffer[]);
}
TEST(tryTest, checkBuffer){
int buffer[10] = {10,1,6,4,3,2,1,3,4,6};
ASSERT_EQ(buffer[0],firstElement(buffer));
}
int main(int argc, char ** argv) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
为简单起见,我将只放置广告文件:
Lib_test.ads
with Interfaces.C;
with Interfaces.C.Pointers;
package Lib_Test is
function FirstElement(a: Interfaces.C.Pointers) return Interfaces.C.Int;
pragma Export(C,FirstElement,"firstElement");
end Lib_Test;
我知道在 c 中,您传递的是指向第一个元素的指针,而不是函数的整个数组。这就是为什么我尝试使用 Interfaces.C.Pointers 作为数据类型但出现以下错误
subtype mark required in this context
found "Pointers" declared at i-cpoint.ads:44
除了 char 数组,我还没有找到使用其他数组类型的好例子。有人可以告诉我如何将 Interfaces.C.Pointers 用于整数数组,甚至如何解决这个问题,我相信这只是我在函数参数中的数据类型。我希望能够访问 ada 函数中的 c 整数数组。
谢谢大家!
根据RM B.3 (70):
An Ada parameter of an array type with component type T, of any mode, is passed as a t* argument to a C function, where t is the C type corresponding to the Ada type T.
因此,不需要使用包 Interfaces.C.Pointers
。您可以只使用 Ada 数组类型。一个小例子:
main.cpp
#include <stdio.h>
#include <gtest/gtest.h>
extern "C" {
void testinit();
void testfinal();
int firstElement(int *buffer);
}
class MyTest : public ::testing::Test {
protected:
MyTest() {
testinit(); // Initialize the Ada library
}
~MyTest() override {
testfinal(); // Finalize the Ada library
}
};
TEST_F(MyTest, CheckBuffer) {
int buffer[10] = {10,1,6,4,3,2,1,3,4,6};
ASSERT_EQ(buffer[0], firstElement(buffer));
}
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
test.gpr
with "libtest";
project Test is
for Source_Dirs use ("src");
for Object_Dir use "obj";
for Main use ("main.cpp");
for Languages use ("C++");
package Compiler is
for Switches ("c++") use ("-I/usr/src/googletest/googletest/include");
end Compiler;
package Linker is
for Switches ("c++") use ("-lgtest", "-lgtest_main", "-pthread", "-ltest");
end Linker;
end Test;
lib_test.ads
with Interfaces.C;
package Lib_Test is
package C renames Interfaces.C;
type Seq is array (0 .. 9) of C.Int;
function First_Element (A : Seq) return C.Int;
pragma Export (C, First_Element, "firstElement");
end Lib_Test;
lib_test.adb
package body Lib_Test is
-------------------
-- First_Element --
-------------------
function First_Element (A : Seq) return C.Int is
begin
return A (A'First);
end First_Element;
end Lib_Test;
libtest.gpr
library project Libtest is
for Library_Kind use "dynamic";
for Library_Name use "test";
for Library_Interface use ("lib_test");
for Library_Auto_Init use "False";
for Library_Dir use "lib";
for Object_Dir use "obj";
for Source_Dirs use ("src");
end Libtest;
输出
$ ./obj/main
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from MyTest
[ RUN ] MyTest.CheckBuffer
[ OK ] MyTest.CheckBuffer (0 ms)
[----------] 1 test from MyTest (0 ms total)
[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (0 ms total)
[ PASSED ] 1 test.
除了@DeeDee 的完整回答之外:如果您真的只想要第一个元素,因为您收到一个指向 int 的指针,以下任何 Ada 声明都应该有效(未经测试!!) :
function First_Element (A : in out C.int) return C.Int;
-- An in/out argument exported with C convention should
-- use a pointer underneath.
function First_Element (A : aliased C.int) return C.Int;
-- Not sure this is already in Ada 95. By marking the
-- argument aliased, it's passed by reference.
function First_Element (A : access C.int) return C.Int;
-- Explicit pointer. I don't like this one (too low level),
-- but it's a possibility.
摆脱你的问题的关键思想是使用实际的指针类型,然后确保使用某种传递引用模式。