Usage of Dynamic Loading
Create two directories named myModuleDirectory
and myExecutableDirectory
under the root directory myProject
of the project. Use cjpm
to build a Cangjie dynamic library module and an executable file in the two directories. The executable file loads the dynamic library module and then uses reflection to manipulate the global variables in the dynamic library module.
$ mkdir -p myProject && cd myProject
$ mkdir -p myPackage && cd myPackage
# Running this command in the myPackage directory initializes the directory structure of the Cangjie dynamic library module, allowing dynamic compilation of Cangjie functionality within myPackage.
$ cjpm init --type=dynamic --name myPackage
cjpm init success
$ cat << EOF > src/myPackage.cj
package myPackage
public var myPublicGlobalVariable0: Int64 = 2333
public let myPublicGlobalVariable1 = MyPublicType("Initializing myPublicGlobalVariable1 in myPackage")
public class MyPublicType {
public MyPublicType(message: String) {
println(message)
}
public static func myPublicStaticMemeberFunction() {
println("myPackage.MyPublicType.myPublicStaticMemeberFunction is called.")
}
static let myStaticVariable = MyPublicType("Initializing myStaticVariable in myPackage.MyPublicType")
}
EOF
# Use cjpm to build the Cangjie dynamic library module.
$ cjpm build
cjpm build success
$ cd .. && mkdir -p myExecutableDirectory && cd myExecutableDirectory
$ cjpm init
$ cat << EOF > src/main.cj
package myExecutableDirectory
import std.reflect.*
main(): Unit {
// Load the Cangjie dynamic library.
let myModule = ModuleInfo.load("../myPackage/target/release/myPackage/libmyPackage.so")
println(myModule.name)
let myPackage = myModule.getPackageInfo("myPackage")
println(myPackage.name)
TypeInfo.get("myPackage.MyPublicType") |> println
let myPublicGlobalVariable0 = myPackage.getVariable("myPublicGlobalVariable0")
(myPublicGlobalVariable0.getValue() as Int64).getOrThrow() |> println
myPublicGlobalVariable0.setValue(666)
(myPublicGlobalVariable0.getValue() as Int64).getOrThrow() |> println
}
EOF
# Build and run the executable program.
$ cjpm run
Initializing myPublicGlobalVariable1 in myPackage
Initializing myStaticVariable in myPackage.MyPublicType
myPackage
myPackage
myPackage.MyPublicType
2333
666
cjpm run finished
$ tree ..
..
├── myExecutableDirectory
│ ├── cjpm.lock
│ ├── cjpm.toml
│ ├── src
│ │ └── main.cj
│ └── target
│ └── release
│ ├── bin
│ │ ├── main
│ │ ├── myExecutableDirectory.bchir2
│ │ └── myExecutableDirectory.cjo
│ ├── myExecutableDirectory
│ │ └── incremental-cache.json
│ └── myExecutableDirectory-cache.json
└── myPackage
├── cjpm.lock
├── cjpm.toml
├── src
│ └── myPackage.cj
└── target
└── release
├── bin
├── myPackage
│ ├── incremental-cache.json
│ ├── libmyPackage.so
│ ├── myPackage.bchir2
│ └── myPackage.cjo
└── myPackage-cache.json
12 directories, 16 files
Note:
The ModuleInfo.load function determines the package name based on the file name. Therefore, the file name cannot be changed. Otherwise, an exception is thrown indicating that the Cangjie dynamic library module file cannot be found.