1 00:00:06,287 --> 00:00:09,510 - Rust supports integration with other languages. 2 00:00:09,510 --> 00:00:13,290 You can call other languages from Rust, typically C. 3 00:00:13,290 --> 00:00:16,260 So a Rust application could call into a C library, 4 00:00:16,260 --> 00:00:18,956 that provides some low level capabilities, for example 5 00:00:18,956 --> 00:00:21,030 and you can do it the other way around as well. 6 00:00:21,030 --> 00:00:23,400 Other languages can call into Rust. 7 00:00:23,400 --> 00:00:25,770 So that could be any language potentially. 8 00:00:25,770 --> 00:00:29,970 So to call another language from Rust, like C, 9 00:00:29,970 --> 00:00:31,140 this is what you do. 10 00:00:31,140 --> 00:00:34,350 You declare the external function that you want to call 11 00:00:34,350 --> 00:00:38,130 and then you call the external function in an unsafe block. 12 00:00:38,130 --> 00:00:40,920 Again, because you're calling into another language, 13 00:00:40,920 --> 00:00:43,260 which is beyond the control of Rust. 14 00:00:43,260 --> 00:00:45,840 Rust must assume that the code is unsafe. 15 00:00:45,840 --> 00:00:49,020 You have to label the block to be unsafe 16 00:00:49,020 --> 00:00:51,993 so that the Rust compiler knows not to check it. 17 00:00:52,860 --> 00:00:55,320 So here's an example where I'm going to call 18 00:00:55,320 --> 00:00:58,140 into a couple of C functions from Rust. 19 00:00:58,140 --> 00:01:00,450 So you declare an external block 20 00:01:00,450 --> 00:01:04,170 and you specify the language that you're gonna call into, C. 21 00:01:04,170 --> 00:01:07,830 And in the C library there's this is a Rust version 22 00:01:07,830 --> 00:01:10,710 of the abs function signature. 23 00:01:10,710 --> 00:01:15,710 So in C there's an abs function which takes a 32 bit integer 24 00:01:15,720 --> 00:01:17,460 and returns the 32 bit integer. 25 00:01:17,460 --> 00:01:19,530 It gives it back the absolute value of an integer, 26 00:01:19,530 --> 00:01:20,910 a positive value. 27 00:01:20,910 --> 00:01:23,250 This is the Rust syntax 28 00:01:23,250 --> 00:01:25,440 for an integer function that takes an integer 29 00:01:25,440 --> 00:01:27,112 and returns an integer. 30 00:01:27,112 --> 00:01:31,440 Okay, so it's like a Rustication of the C prototype. 31 00:01:31,440 --> 00:01:34,830 And in C there's also a function called F abs, fabs 32 00:01:34,830 --> 00:01:36,180 which takes a double 33 00:01:36,180 --> 00:01:39,900 that's a 64 bit float and returns a double. 34 00:01:39,900 --> 00:01:41,250 It gives you, you pass in a double 35 00:01:41,250 --> 00:01:43,515 it gives you back the absolute value of that double. 36 00:01:43,515 --> 00:01:47,610 So these functions already exist in the C library. 37 00:01:47,610 --> 00:01:49,140 I've declared them here 38 00:01:49,140 --> 00:01:50,820 and then if I want to call them from Rust, 39 00:01:50,820 --> 00:01:52,230 I have an unsafe block. 40 00:01:52,230 --> 00:01:53,250 And you just call the functions. 41 00:01:53,250 --> 00:01:54,540 It is literally as simple as that. 42 00:01:54,540 --> 00:01:56,010 You pass in an integer 43 00:01:56,010 --> 00:01:58,620 and it'll call into the underlying C library. 44 00:01:58,620 --> 00:02:03,150 We turn it back integer into 32, call the F abs function 45 00:02:03,150 --> 00:02:05,490 passing in a double 64 bit float 46 00:02:05,490 --> 00:02:08,940 get back a 64 bit float with a positive value. 47 00:02:08,940 --> 00:02:13,620 So this is how Rust can call into other languages, like C. 48 00:02:13,620 --> 00:02:15,000 Doing it the other way round 49 00:02:15,000 --> 00:02:18,150 making a Rust function callable in another language. 50 00:02:18,150 --> 00:02:19,170 In order to make a function 51 00:02:19,170 --> 00:02:21,900 in Rust callable in another language 52 00:02:21,900 --> 00:02:24,640 you mark the function as externally visible. 53 00:02:24,640 --> 00:02:26,280 You also make sure 54 00:02:26,280 --> 00:02:28,980 that the function name isn't mangled by Rust. 55 00:02:28,980 --> 00:02:31,920 Rust can mangle names internally, 56 00:02:31,920 --> 00:02:33,870 bit like the way C plus plus does, 57 00:02:33,870 --> 00:02:35,790 you want to disable the name mangling. 58 00:02:35,790 --> 00:02:39,030 So the function name is exactly as you specified 59 00:02:39,030 --> 00:02:41,220 so that the client language, C 60 00:02:41,220 --> 00:02:43,560 knows what the name of the function really is. 61 00:02:43,560 --> 00:02:45,030 So here's an example. 62 00:02:45,030 --> 00:02:48,030 There's an attribute, no mangle 63 00:02:48,030 --> 00:02:52,380 that's a standard Rust attribute, like a compiler directive. 64 00:02:52,380 --> 00:02:56,490 I declare as a public extern visible in the C language. 65 00:02:56,490 --> 00:02:59,430 My function, this is just a regular Rust function. 66 00:02:59,430 --> 00:03:03,420 You can call me from C, you can also call it from Rust. 67 00:03:03,420 --> 00:03:05,610 It's just a regular function actually. 68 00:03:05,610 --> 00:03:06,713 So you can call it from Rust 69 00:03:06,713 --> 00:03:09,990 and you can also call it from C if you want to. 70 00:03:09,990 --> 00:03:11,343 It's kind of been exported. 71 00:03:12,330 --> 00:03:13,410 Right 72 00:03:13,410 --> 00:03:16,170 So time for an example, 73 00:03:16,170 --> 00:03:19,320 usual project less than 15 additional Rust techniques. 74 00:03:19,320 --> 00:03:20,760 We'll have a look at the main 75 00:03:20,760 --> 00:03:23,040 and then we'll see other language, 76 00:03:23,040 --> 00:03:25,383 a demo language integration. 77 00:03:27,180 --> 00:03:28,080 Okay then. 78 00:03:28,080 --> 00:03:32,170 So in main, I'm gonna uncomment this demo 79 00:03:33,930 --> 00:03:36,630 and here it is. 80 00:03:36,630 --> 00:03:41,630 So I've declared some external functions that exist in C. 81 00:03:41,970 --> 00:03:43,530 Those functions exist already. 82 00:03:43,530 --> 00:03:44,760 Abs and fabs. 83 00:03:44,760 --> 00:03:47,310 I'm going to call those functions in my code. 84 00:03:47,310 --> 00:03:49,950 You can only call other language functions 85 00:03:49,950 --> 00:03:51,480 in an unsafe block. 86 00:03:51,480 --> 00:03:54,300 Okay. So down here I have an unsafe block 87 00:03:54,300 --> 00:03:56,790 and I call functions which are unsafe. 88 00:03:56,790 --> 00:03:58,990 I call abs the first one 89 00:04:00,870 --> 00:04:04,980 and then I call fabs the second one. 90 00:04:04,980 --> 00:04:08,310 And for good measure, I've also got my own unsafe function. 91 00:04:08,310 --> 00:04:10,110 All right bring it into view at the bottom. 92 00:04:10,110 --> 00:04:12,300 I've got an unsafe function, which 93 00:04:12,300 --> 00:04:14,820 potentially could be doing something a little bit edgy. 94 00:04:14,820 --> 00:04:17,010 I mean it's not actually pushing the boat out too much 95 00:04:17,010 --> 00:04:18,930 it's just returning the meaning of life, 96 00:04:18,930 --> 00:04:19,950 the universe and everything. 97 00:04:19,950 --> 00:04:22,230 But it's officially unsafe. 98 00:04:22,230 --> 00:04:24,510 Maybe it's doing point arithmetic or something. 99 00:04:24,510 --> 00:04:27,810 So if you have an unsafe function here 100 00:04:27,810 --> 00:04:30,690 then you can only call that function in an unsafe block. 101 00:04:30,690 --> 00:04:34,890 So this unsafe block can call into C language functions 102 00:04:34,890 --> 00:04:37,440 and it can call into my own unsafe functions as well, 103 00:04:37,440 --> 00:04:39,030 if I have any. 104 00:04:39,030 --> 00:04:42,483 Okay, so that's call in from Rust into C. 105 00:04:42,483 --> 00:04:44,640 The other way round, 106 00:04:44,640 --> 00:04:46,380 if you have a Rust function 107 00:04:46,380 --> 00:04:48,870 that you want to be callable from C, 108 00:04:48,870 --> 00:04:52,680 here is such a function, I suppress mangling, 109 00:04:52,680 --> 00:04:55,440 I declare the function as publicly visible 110 00:04:55,440 --> 00:04:57,870 to a C application. 111 00:04:57,870 --> 00:04:59,070 And the name of the function 112 00:04:59,070 --> 00:05:01,620 the code in here is just a regular function. 113 00:05:01,620 --> 00:05:03,270 It really is just regular Rust. 114 00:05:03,270 --> 00:05:05,370 You have to be a bit careful about parameters 115 00:05:05,370 --> 00:05:09,930 because C might find it difficult to pass in complex types. 116 00:05:09,930 --> 00:05:11,670 So when you pass, if you have parameters in here 117 00:05:11,670 --> 00:05:13,620 you might want to restrict yourself 118 00:05:13,620 --> 00:05:16,680 to things like, you know, raw integers for example 119 00:05:16,680 --> 00:05:18,520 rather than anything too ambitious 120 00:05:19,440 --> 00:05:22,230 to make it easier to bind into from another language. 121 00:05:22,230 --> 00:05:25,470 So you know, don't go overboard. 122 00:05:25,470 --> 00:05:28,170 So anyway, this function has been publicly exported. 123 00:05:28,170 --> 00:05:30,030 So I could, if I had a C application 124 00:05:30,030 --> 00:05:33,180 I could call this function from C. 125 00:05:33,180 --> 00:05:36,540 Okay. It is just a regular Rust function though 126 00:05:36,540 --> 00:05:39,990 so I could actually call it from my own Rust code. 127 00:05:39,990 --> 00:05:41,940 And I've done that actually towards the bottom 128 00:05:41,940 --> 00:05:45,300 of my, this is my kind of driver function here. 129 00:05:45,300 --> 00:05:47,250 Towards the bottom you can see 130 00:05:47,250 --> 00:05:48,930 I have actually invoked that function. 131 00:05:48,930 --> 00:05:53,070 Okay. So that's allowable and the function isn't unsafe 132 00:05:53,070 --> 00:05:55,110 it's just a regular Rust function. 133 00:05:55,110 --> 00:05:58,170 So I can call that function in a normal code block 134 00:05:58,170 --> 00:06:01,448 that doesn't need to be marked as unsafe. 135 00:06:01,448 --> 00:06:04,263 Okay. So we'll run the example. 136 00:06:05,317 --> 00:06:06,150 [Typing] 137 00:06:11,550 --> 00:06:12,383 There we are. 138 00:06:12,383 --> 00:06:13,260 That's marvelous. 139 00:06:13,260 --> 00:06:14,610 It's absolutely super. 140 00:06:14,610 --> 00:06:15,786 So here was the call 141 00:06:15,786 --> 00:06:19,200 to the abs function from the C library. 142 00:06:19,200 --> 00:06:23,460 And here's the call to the fabs function in the C library. 143 00:06:23,460 --> 00:06:25,072 And then finally, by the way 144 00:06:25,072 --> 00:06:27,870 I've called my unsafe function, which returns 145 00:06:27,870 --> 00:06:30,270 the meaning of life, the universe and everything. 146 00:06:30,270 --> 00:06:32,490 And then finally the function 147 00:06:32,490 --> 00:06:33,630 which could be called from C, 148 00:06:33,630 --> 00:06:36,300 but can also be called from Rust greetings 149 00:06:36,300 --> 00:06:38,190 from my Rust function. 150 00:06:38,190 --> 00:06:41,250 So that's the end of the lesson and that's also the end 151 00:06:41,250 --> 00:06:44,853 of the kind of theoretical part of the course. 152 00:06:44,853 --> 00:06:47,430 What we're gonna do in the final two lessons 153 00:06:47,430 --> 00:06:49,680 is apply the knowledge that we've got 154 00:06:49,680 --> 00:06:50,700 and the syntax we've learned 155 00:06:50,700 --> 00:06:52,194 and the libraries that we've discovered 156 00:06:52,194 --> 00:06:54,335 and apply those techniques 157 00:06:54,335 --> 00:06:57,630 into real applications as a case study. 158 00:06:57,630 --> 00:07:00,810 So I've got a a work project in the next lesson 159 00:07:00,810 --> 00:07:02,610 that shows how to do file handling, 160 00:07:02,610 --> 00:07:04,710 reading CSV files, data handling 161 00:07:04,710 --> 00:07:08,280 and talking about how to structure a large application. 162 00:07:08,280 --> 00:07:10,800 And then in the final lesson after that 163 00:07:10,800 --> 00:07:12,330 we're going to look at database access 164 00:07:12,330 --> 00:07:14,703 which be quite a nice way to round things off.