-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cannot use .importcpp type with non-public default constructor as a return type of a proc #4687
Comments
Ugly workaround: {.emit:"""
class Test {
private:
Test() {}
public:
Test(int x) {}
};
"""}
type
Test {.importcpp: "Test", nodecl.} = object
proc initTest(x: cint): Test {.importcpp: "Test(@)", nodecl.}
proc mkTest(x: int): Test {.asmNoStackFrame.} =
{.emit: "return Test(`x`);".} |
@vegansk
(Nim codegen declares |
You can try this techique: https://github.com/vegansk/nimtests/blob/master/ffi/raii/raii.nim |
@vegansk Do you mean returning pointer instead of the object? Unfortunately, that's not an option for me, I have to mimic signature as required by the framework. If there was a way to force Nim to not generate |
You can declare the proc as |
@Araq the change for type
Vector {.importcpp: "std::vector", header: "vector".} [T] = object
proc initVector[T](): Vector[T] {.importcpp: "std::vector<'*0 >()", header: "vector", constructor.}
proc add[T](vec: Vector[T], item: T) {.importcpp: "push_back", header: "vector".}
proc initVectorWithItem[T](item: T): Vector[T] {.noinit.} =
result = initVector[T]()
if false:
return
result.add(item)
discard initVectorWithItem(1) |
Yeah well, it's hard to support it without rewriting the codegen. C++ hates labels and goto and a codegenerator loves it. |
This issue has been automatically marked as stale because it has not had recent activity. If you think it is still a valid issue, write a comment below; otherwise it will be closed. Thank you for your contributions. |
- workaround a disappearing typedesc arg - workaround no-default constructor: nim-lang/Nim#4687
Now there is a workaround for most of the cases: https://nim-lang.github.io/Nim/manual_experimental.html#constructor-initializer |
Similar problem happens when the imported C++ class doesn't have a copy constructor or a copy assignment operator. uncopyable.hpp: #pragma once
#include <iostream>
using namespace std;
struct Uncopyable {
Uncopyable() {
cout << "Uncopyable()\n";
}
Uncopyable(int x): x(x) {
cout << "Uncopyable(" << x << ")\n";
}
Uncopyable(const Uncopyable&) = delete;
Uncopyable& operator = (const Uncopyable&) = delete;
void print() {
cout << "Uncopyable::print: " << x << endl;
}
int x;
};
testnocpy.cpp #include "uncopyable.hpp"
Uncopyable initUncopyableInCpp(int x) {
return Uncopyable(x);
}
int main() {
auto a = initUncopyableInCpp(123);
a.print();
return 0;
} Compile and run: $ g++ testnocpy.cpp
$ ./a.out
Uncopyable(123)
Uncopyable::print: 123 Copy constructor and copy assignment operator of Following Nim code imports type
Uncopyable {.header: "uncopyable.hpp".} = object
x: cint
proc constructUncopyable(x: cint): Uncopyable {.header: "uncopyable.hpp", importcpp: "Uncopyable(@)", constructor.}
proc print(x: Uncopyable) {.header: "uncopyable.hpp", importcpp.}
proc initUncopyableInNim(x: cint): Uncopyable =
constructUncopyable(x)
proc main =
let a = initUncopyableInNim(5)
a.print()
main() $ nim cpp -r -f testnocpy.nim
CC: testnocpy.nim
@mtestnocpy.nim.cpp: In function ‘Uncopyable initUncopyableInNim__testnocpy_u7(int)’:
@mtestnocpy.nim.cpp:70:49: Error: use of deleted function ‘Uncopyable& Uncopyable::operator=(
const Uncopyable&)’
70 | nimln_(9); result = Uncopyable(x_p0);
| ^
uncopyable.hpp: // Uncopyable(const Uncopyable&) = delete;
// Uncopyable& operator = (const Uncopyable&) = delete; or implementing them: Uncopyable(const Uncopyable& src): x(src.x) {
cout << "Uncopyable(const Uncopyable&)\n";
}
Uncopyable& operator = (const Uncopyable& src) {
cout << "Copy Uncopyable\n";
x = src.x;
return *this;
} $ nim cpp -r -f testnocpy.nim
Uncopyable()
Uncopyable(5)
Copy Uncopyable
Uncopyable(const Uncopyable&)
Uncopyable::print: 5 But it calls default constructor and copy constructor. In |
Because Nim codegen declares
result
variable at the beginning of a proc, it always tries to invoke the object's default constructor when compiling to C++ backend. But, when dealing with wrappers (UE4 in my case), some imported types don't have the default constructor, and so it's impossible to define Nim procedure that returns a value of that type.The text was updated successfully, but these errors were encountered: